【ZJOI2007】【BZOJ1059】矩阵游戏 匈牙利算法
题目描述
输入格式
输出格式
样例
数据范围与提示
solution:
这是一道神仙题。。。我没想到用二分图过
题目要求我们经过几次换行换列操作,使得方阵的主对角线(左上角到右下角的连线)上的格子均为黑色。
如果我们把黑点看成一条边,行看成一组点,列看成另一组点,那么map[i][j]=1表示由行上的i点连一条边到列上的j点,这样就变成了一个二分图
通过分析一些样例我们发现,如果这个二分图的最大匹配恰好等于n,则有解
现在看来这是一道裸的匈牙利,连图都是直接输入的。
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int n,t,map[205][205],ans,result[205]; bool vis[205]; bool find(int x){ for(int i=1;i<=n;i++){ if(map[x][i]==1&&vis[i]==0){ vis[i]=1; if(result[i]==0||find(result[i])){ result[i]=x; return 1; } } } return 0; } int main(){ scanf("%d",&t); while(t--){ memset(vis,0,sizeof(vis)); memset(map,0,sizeof(map)); memset(result,0,sizeof(result)); ans=0; scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&map[i][j]); for(int i=1;i<=n;i++){ memset(vis,0,sizeof(vis)); if(find(i)) ans++; } if(ans==n) printf("Yes\n"); else printf("No\n"); } return 0; }