uva 10092 The Problem with the Problem Setter 二分图匹配 匈牙利算法
2017-11-14 01:15
751 查看
题意:第一行k,p 分别为 题目的类别数 题目的个数
第二行k个数 为每类题的个数
接下来p行 每行第一个数(设为n)为 该题可被划分到的类别的个数 接下来n个数为 可被划分到第几个类别
然后题目希望你能把这些题划分到他可以被划分到的类 使得最后每类题的数量达到要求。
首先想到这是二分图匹配 然后想了一下 从以前做过的题目中找到了灵感
就是把要求的数量拆开 比如第一个样例 三类题 1 2 3 要求数量为 3 3 4
那么我就可以拆分成十个点 前三个标志为1 接下来三个标志为 2 后四个点标志为3 ,添加标志是为了方便接下来建边
拆分,标记完之后就可以建边了 如果这个点可以被分配的类别与标志相同 就建一条边
然后就可以进行匈牙利算法了,返回值和n比 ,相同则输出1 然后把匈牙利算法中的存匹配的点的数组对应输出即可
不同则输出0
第二行k个数 为每类题的个数
接下来p行 每行第一个数(设为n)为 该题可被划分到的类别的个数 接下来n个数为 可被划分到第几个类别
然后题目希望你能把这些题划分到他可以被划分到的类 使得最后每类题的数量达到要求。
首先想到这是二分图匹配 然后想了一下 从以前做过的题目中找到了灵感
就是把要求的数量拆开 比如第一个样例 三类题 1 2 3 要求数量为 3 3 4
那么我就可以拆分成十个点 前三个标志为1 接下来三个标志为 2 后四个点标志为3 ,添加标志是为了方便接下来建边
拆分,标记完之后就可以建边了 如果这个点可以被分配的类别与标志相同 就建一条边
然后就可以进行匈牙利算法了,返回值和n比 ,相同则输出1 然后把匈牙利算法中的存匹配的点的数组对应输出即可
不同则输出0
#include<bits/stdc++.h> using namespace std; const int maxn=100005; struct Edge { int from; int to; Edge(int f, int t):from(f), to(t){} }; vector<int> G[maxn]; vector<Edge> edges; int matching[maxn]; int check[maxn]; queue<int> Q; int n; int prev1[maxn]; int Hungarian() { int ans = 0; memset(matching, -1, sizeof(matching)); memset(check, -1, sizeof(check)); for (int i=0;i<n; ++i) { if (matching[i] == -1) { while (!Q.empty()) Q.pop(); Q.push(i); prev1[i]=-1; bool flag = false; while (!Q.empty() && !flag) { int u = Q.front(); for (auto ix = G[u].begin(); ix != G[u].end() && !flag; ++ix) { int v = edges[*ix].to; if (check[v] != i) { check[v] = i; Q.push(matching[v]); if (matching[v] >= 0) { prev1[matching[v]] = u; } else { flag = true; int d=u, e=v; while (d != -1) { int t = matching[d]; matching[d] = e; matching[e] = d; d = prev1[d]; e = t; } } } } Q.pop(); } if (matching[i] != -1) ++ans; } } return ans; } int num[105]; int match[105]; int main() { int i,j,k,s,v,p,m,x,y; while(cin>>k>>p) { if(k==0&&p==0) break; n=0; for(i=1;i<=k;i++) { cin>>num[i]; for(j=0;j<num[i];j++) match[n++]=i; } for(i=0;i<p;i++) { cin>>m; for(j=0;j<m;j++) { cin>>x; for(y=0;y<n;y++) { if(match[y]==x) { edges.push_back(Edge(y,i+n)); G[y].push_back(edges.size()-1); } } } } int ans=Hungarian(); if(ans==n) { cout<<'1'<<endl; int res=0; for(i=1;i<=k;i++) { for(j=0;j<num[i];j++) { cout<<matching[res++]-n+1<<' '; } cout<<endl; } } else cout<<'0'<<endl; for(i=0;i<n+m;i++) G[i].clear(); edges.clear(); } return 0; }
相关文章推荐
- UVA 10092 The Problem with the Problemsetter【二分图最大匹配变形 邻接矩阵实现最大匹配算法】
- UVa 10092 The Problem With the Problem Setter ( SAP )
- uva10092 The Problem with the Problemsetter
- UVA 10092 The Problem with the Problemsetter
- UVa Problem 10092 The Problem With the Problem Setter (命题者的难题)
- HDU 3729 I'm Telling the Truth(二分图匹配+匈牙利算法+变形)
- POJ 1274 The Perfect Stall(二分图匹配/匈牙利算法)
- The Accomodation of Students HDU - 2444(二分图匹配,匈牙利算法)
- 【hdu 3861】The King’s Problem(Tarjan缩点+匈牙利算法)
- zoj 1654 Place the Robots(二分图匹配 匈牙利算法)
- POJ_P1274 The Perfect Stall(二分图匹配+匈牙利算法)
- 二分图最大匹配(匈牙利算法) UVA 670 The dog task
- UVA 12168 Cat vs. Dog(二分图匹配+匈牙利算法+最大独立集+数据转化)
- ZOJ 1654 匈牙利算法 二分图匹配 Place the Robots
- USACO 4.2 The Perfect Stall(二分图匹配匈牙利算法)
- uva 101 The Blocks Problem (基本算法-模拟)
- HDU 2444 The Accomodation of Students (二分图匹配+匈牙利算法+bfs判断是否为二分图)
- HDU2444 The Accomodation of Students(二分图匹配,匈牙利算法,DFS)
- uva 101 The Blocks Problem (基本算法-模拟)
- UVa 10025 The ? 1 ? 2 ? ... ? n = k problem (数学&想法题&常数算法)