码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 2819 记录路径的二分匹配

时间:2015-05-14 23:49:28      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:

题目大意就是给出一个矩阵,每个格子里面要么是0, 要么是1;是否能够经过交换(交换行或者列)使得主对角线上都是1。

其实就行和列的匹配,左边是行,右边是列,然后如果行列交点是1,那么就可以匹配,看是否为完美匹配,然后输出怎么交换的。开始很蒙的,后来仔细去 想,可以这样理解,想要对角线上都是1,那么我们就可以锁定行,来选择列和它匹配,将选择的列移动到和该行形成对角线上是1的位置,比如和第一行匹配的 列,就要移动要第一列,第二行的,就到第二列。其实就是对第i行,找一个第i个数是1的列和它匹配,然后看是否是最大匹配!

路径的输出其实就是 调整匹配使之都为横线,调整的过程就是要输出的路径,调整列和行是相同的,所以锁定一个方向就行了

Sample Input

2
0 1
1 0
2
1 0
1 0
Sample Output
1
R 1 2
-1

2015-05-14:
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 #include<map>
 8 using namespace std;
 9 #define MOD 1000000007
10 const int INF=0x3f3f3f3f;
11 const double eps=1e-5;
12 typedef long long ll;
13 #define cl(a) memset(a,0,sizeof(a))
14 #define ts printf("*****\n");
15 int n,m,tt;
16 const int MAXN = 510;
17 int a[10000],b[10000];
18 int uN,vN;//u,v的数目,使用前面必须赋值
19 int g[MAXN][MAXN];//邻接矩阵
20 int linker[MAXN];
21 bool used[MAXN];
22 bool dfs(int u)
23 {
24     for(int v = 0; v < vN;v++)
25     if(g[u][v] && !used[v])
26     {
27         used[v] = true;
28         if(linker[v] == -1 || dfs(linker[v]))
29         {
30             linker[v] = u;
31             return true;
32         }
33     }
34     return false;
35 }
36 int hungary()
37 {
38     int res = 0;
39     memset(linker,-1,sizeof(linker));
40     for(int u = 0;u < uN;u++)
41     {
42         memset(used,false,sizeof(used));
43         if(dfs(u))res++;
44     }
45     return res;
46 }
47 int main()
48 {
49     int i,j,k;
50     #ifndef ONLINE_JUDGE
51     freopen("1.in","r",stdin);
52     #endif
53     while(scanf("%d",&n)!=EOF)
54     {
55         uN=vN=n;
56         for(i=0;i<n;i++)
57             for(j=0;j<n;j++)    scanf("%d",&g[i][j]);
58         int ans=hungary();
59         if(ans<n)
60         {
61             printf("-1\n");
62             continue;
63         }
64         int res=0;
65         for(i=0;i<n;i++)
66         {
67             for(j=0;j<n;j++)
68             {
69                 if(linker[j]==i)    break;
70             }
71             if(i!=j)
72             {
73                 a[res]=i,b[res++]=j;
74                 int temp=linker[j];
75                 linker[j]=linker[i];
76                 linker[i]=temp;
77             }
78         }
79         printf("%d\n",res);
80         for(i=0;i<res;i++)
81         {
82             printf("C %d %d\n",a[i]+1,b[i]+1);
83         }
84     }
85 }

 

 

hdu 2819 记录路径的二分匹配

标签:

原文地址:http://www.cnblogs.com/cnblogs321114287/p/4284181.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!