POJ 1719 Shooting Contest 二分图最大匹配

来源:互联网 发布:中南大学网络教育课程 编辑:程序博客网 时间:2024/06/10 13:15

题目大意:给出一张表格,m行n列,每一列有两个白色的格子。现在要选出n个格子,使得每列恰好有一个格子,每行至少有一个格子。输出每一列选的格子在第几行。无解输出“NO”。(有SpecialJugde)


思路:二维的图,选点,很经典的二分图的模型。建完模之后,做最大匹配。这样首先要保证每一行要能被匹配到,如果max_match小于行数就输出NO。满足了每一行都有一个格子之后,要考虑每一列。现在每一列的状态是有格子和没格子。有格子的已经满足了,没有格子的只要任选一个格子就可以,因为不影响列上的情况(列要求至少有一个格子)。


CODE:


#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAX 1010using namespace std;int cases;int m,n;bool map[MAX][MAX];inline void Initialize();bool Hungary(int x);int main(){for(cin >> cases;cases; --cases) {scanf("%d%d",&m,&n);Initialize();for(int x,y,i = 1;i <= n; ++i) {scanf("%d%d",&x,&y);map[x][i] = map[y][i] = true;}for(int i = 1;i <= m; ++i) {memset(v,false,sizeof(v));ans += Hungary(i);}if(ans < m)puts("NO");else {for(int i = 1;i <= n; ++i)if(paired[i])printf("%d ",paired[i]);elsefor(int j = 1;j <= m; ++j)if(map[i][j]) {printf("%d ",j);break;}puts("");}}return 0;}inline void Initialize(){memset(map,false,sizeof(map));}bool Hungary(int x){for(int i = 1;i <= n; ++i) if(map[x][i] && !v[i]) {v[i] = true;if(!paired[i] || Hungary(paired[i])) {paired[i] = x;return true;}}return false;}


0 0
原创粉丝点击