POJ1719二分匹配

第一次发文,就是一些学习的心得而已,自己忘得时候就可以来看看,好了废话不多说,直接说说这题的思路。

题意大概是每列只能射中一个白格子,每行可以射多个,让你输出这样的序列,明显的二分图求匹配,用列去选行就可以了,但是列有可能比行数大,所以就分两种情况。只有匹配值等于行数才有解,不然无解,当列数大于行数时在得到的序列尾部加点东西就好了(再多余出的列里每列随便选个白格子)

上代码,刚开始是用vector建的图,然后叫上去就报运行错误,找了好久没发现错误,一气之下改成矩阵直接撸........=。=

 1  #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<vector>
 5 #define maxn 1050
 6 
 7 using namespace std;
 8 
 9 int link[maxn],vis[maxn];
10 int g[maxn][maxn];
11 int r,c;
12 
13 int dfs(int x)
14 {
15     for(int i=1;i<=r;i++)
16     {
17         if(g[x][i]&&!vis[i])
18         {
19             vis[i]=1;
20             if(link[i]==-1||dfs(link[i]))
21             {
22                 link[i]=x;
23                 return 1;
24             }
25         }
26     }
27     return 0;
28 }
29 void solve()
30 {
31     int sum=0;
32     memset(link,-1,sizeof(link));
33     for(int i=1;i<=r;i++)
34     {
35         memset(vis,0,sizeof(vis));
36         if(dfs(i)) sum++;
37     }
38  //   printf("%d
",sum);
39     if(sum==r)
40     {
41         for(int j=1;j<r;j++)
42             printf("%d ",link[j]);
43         printf("%d",link[r]);
44         for(int k=r+1;k<=c;k++)
45         {
46             for(int l=1;l<=r;l++)
47             {
48                 if(g[l][k])
49                 {
50                     printf(" %d",l);
51                     break;
52                 }
53             }
54         }
55         puts("");
56     }
57     else puts("NO");
58 }
59 int main()
60 {
61     int t;
62     scanf("%d",&t);
63     while(t--)
64     {
65         scanf("%d %d",&r,&c);
66         memset(g,0,sizeof(g));
67         for(int i=1;i<=c;i++)
68         {
69             int a,b;
70             scanf("%d %d",&a,&b);
71             g[a][i]=g[b][i]=1;
72         }
73         solve();
74     }
75     return 0;
76 }
View Code

#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#define maxn 1050

using namespace std;

int link[maxn],vis[maxn];
int g[maxn][maxn];
int r,c;

int dfs(int x)
{
for(int i=1;i<=r;i++)
{
if(g[x][i]&&!vis[i])
{
vis[i]=1;
if(link[i]==-1||dfs(link[i]))
{
link[i]=x;
return 1;
}
}
}
return 0;
}
void solve()
{
int sum=0;
memset(link,-1,sizeof(link));
for(int i=1;i<=r;i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i)) sum++;
}
// printf("%d ",sum);
if(sum==r)
{
for(int j=1;j<r;j++)
printf("%d ",link[j]);
printf("%d",link[r]);
for(int k=r+1;k<=c;k++)
{
for(int l=1;l<=r;l++)
{
if(g[l][k])
{
printf(" %d",l);
break;
}
}
}
puts("");
}
else puts("NO");
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&r,&c);
memset(g,0,sizeof(g));
for(int i=1;i<=c;i++)
{
int a,b;
scanf("%d %d",&a,&b);
g[a][i]=g[b][i]=1;
}
solve();
}
return 0;
}

原文地址:https://www.cnblogs.com/liboyan/p/4390300.html