hdu 2819 Swap 二分图匹配

来源:互联网 发布:three.js lookat 编辑:程序博客网 时间:2024/04/30 01:17
#include<cstdio>#include<cstring>#include<vector>#include<algorithm>using namespace std;#define N 110vector<int>g[N];int linker[N];bool vis[N];int a[N];int b[N];bool dfs(int u){for(int i=0;i<g[u].size();i++){int v=g[u][i];if(vis[v]) continue;vis[v]=true;if(linker[v]==-1||dfs(linker[v])){linker[v]=u;return true;}}return false;}int hungary(int n){int cnt=0;memset(linker,-1,sizeof(linker));for(int i=0;i<n;i++){memset(vis,0,sizeof(vis));if(dfs(i)) cnt++;}return cnt;}int main(){int n;while(scanf("%d",&n)!=EOF){int x;for(int i=0;i<n;i++){g[i].clear();for(int j=0;j<n;j++){scanf("%d",&x);if(x==1){g[i].push_back(j);}}}int ans=hungary(n);if(ans!=n){printf("-1\n");continue;}int cnt=0;for(int i=0;i<n;i++){int pos=i;for(int j=0;j<n;j++){if(linker[j]==i){pos=j;break;}}if(pos!=i){//列列进行交换linker[pos]=linker[i];linker[i]=i;a[cnt]=i;b[cnt++]=pos;}}printf("%d\n",cnt);for(int i=0;i<cnt;i++){printf("C %d %d\n",a[i]+1,b[i]+1);}}return 0;}
要实现对角线上都是一,则需要出现不同列上都有1并且这些列不在同一行(这样才能移动出结果),这就是明显的二分图匹配问题了,行是一个集合,列是一个集合,判断这两个集合的最大匹配数是否为n就行了。题目中只是说要找出一种情况,只移动行或列都行的,因为我是用行来匹配列的,所以移动的是列。
0 0
原创粉丝点击