hdu 2819 记录路径的二分匹配

题目大意就是给出一个矩阵,每个格子里面要么是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 }
时间: 2024-08-14 11:17:41

hdu 2819 记录路径的二分匹配的相关文章

hdu 1507 记录路径的二分匹配

题意:N*M的矩形,向其中填充1*2的小块矩形,黑色的部分不能填充,问最多可以填充多少块.链接:点我 黑白棋最大匹配 将棋盘中i+j为奇数的做A集合,偶数的做B集合,相邻的则建立联系.于是便转换成寻找最大匹配的问题 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<que

hdu 2819 Swap【完美二分匹配】

Swap Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2514    Accepted Submission(s): 900 Special Judge Problem Description Given an N*N matrix with each entry equal to 0 or 1. You can swap any

hdu 2768 Cat vs. Dog (二分匹配)

Cat vs. Dog Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1422    Accepted Submission(s): 534 Problem Description The latest reality show has hit the TV: ``Cat vs. Dog''. In this show, a bunch

hdu 5093 Battle ships 最大二分匹配

Battle ships Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 589    Accepted Submission(s): 233 Problem Description Dear contestant, now you are an excellent navy commander, who is responsible

HDU - 1045 Fire Net(二分匹配)

Description Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall. A blockhouse is a small castle that has four openings through which to s

hdu 4619 Warm up 2 (二分匹配)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4619 题意: 平面上有一些1×2的骨牌,每张骨牌要么水平放置,要么竖直放置,并且保证同方向放置的骨牌不会相互覆盖.水平放置的牌和竖直放置的牌可能相互覆盖,现在要移去一些牌,使得剩下的牌任何两张都不会相互覆盖,问桌面上最多能剩多少张牌. 分析: 如果把每张牌看作一个结点,则共有两类结点,容易联想到二分图.另外,同方向的牌不会相互覆盖,不同方向的可能相互覆盖,易想到二分图的一个重要性质:同类结点间不会连

HDU 2063 过山车(二分匹配入门)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2063 二分匹配最大匹配数简单题,匈牙利算法.学习二分匹配传送门:http://blog.csdn.net/dark_scope/article/details/8880547 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 using nam

HDU 2063 过山车 (二分匹配之匈牙利算法)

过山车 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 12475    Accepted Submission(s): 5446 Problem Description RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了.可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做pa

hdu 1150 Machine Schedule (经典二分匹配)

//A组n人 B组m人 //最多有多少人匹配 每人仅仅有匹配一次 # include<stdio.h> # include<string.h> # include<algorithm> using namespace std; int n,m,k; int pp[1100][1100],map[1100],vis[1100]; int bfs(int x)//二分匹配模板 { for(int i=1;i<=m;i++)//B组中的人来迎合匹配 { if(!vis[