HDU 2819 Swap

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2819

解题思路:

这道题是要把n×n的矩阵的对角线全部变为一。

然后我们把纵坐标,横坐标分别为二分图的左右两个集合,如果要对角线全部为1。

首先要满足的条件是:

这个二分图的最大匹配数,必须为N,如果小于肯定不能满足题意。换句话说每一个列都必须和一个行有匹配。

然后进行交换就行了。

实现代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int MAXN=105;
 8 int g[MAXN][MAXN],used[MAXN];
 9 int linker[MAXN];
10 int N;
11 int a[MAXN*10],b[MAXN*10];
12 
13 bool dfs(int u){
14     for(int i=1;i<=N;i++){
15         if(!used[i]&&g[u][i]){
16             used[i]=1;
17             if(linker[i]==-1||dfs(linker[i])){
18                 linker[i]=u;
19                 return true;
20             }
21         }
22     }
23     return false;
24 }
25 
26 int hungry(){
27     memset(linker,-1,sizeof(linker));
28     int res=0;
29 
30     for(int i=1;i<=N;i++){
31         memset(used,0,sizeof(used));
32         if(dfs(i))
33             res++;
34     }
35     return res;
36 }
37 
38 int main(){
39     while(scanf("%d",&N)!=EOF){
40         for(int i=1;i<=N;i++)
41             for(int j=1;j<=N;j++)
42                 scanf("%d",&g[i][j]);
43 
44         int ans=hungry();
45         if(ans<N){
46             printf("-1
");
47             continue;
48         }
49 
50         int res=0;
51         int i,j;
52             for(i=1;i<=N;i++){
53                 
54                 //第i列要和和与第i行匹配的列相交换。
55                 for(j=i;j<=N;j++)
56                     if(linker[j]==i)
57                         break;
58                 if(i!=j){
59                     a[res]=i;b[res++]=j;
60                     swap(linker[i],linker[j]);
61                 }
62             }
63 
64          printf("%d
",res);
65         for(i=0;i<res;i++)
66             printf("C %d %d
",a[i],b[i]);
67         }
68 
69     }
自己选的路,跪着也要把它走完------ACM坑
原文地址:https://www.cnblogs.com/IKnowYou0/p/6553569.html