POJ 1469 COURSES 二分图最大匹配 二分图

http://poj.org/problem?id=1469

这道题我绝壁写过但是以前没有mark过二分图最大匹配的代码mark一下。

匈牙利 O(mn)

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<queue>
 7 using namespace std;
 8 #define LL long long
 9 const int maxn=310;
10 int n,m;
11 struct nod{
12     int y,next;
13 }e[maxn*maxn];
14 int head[maxn]={},tot=0;
15 int p[maxn]={},vis[maxn]={};
16 inline void init(int x,int y){e[++tot].y=y;e[tot].next=head[x];head[x]=tot;}
17 bool dfs(int x){
18     for(int i=head[x];i;i=e[i].next){
19         if(!vis[e[i].y]){
20             vis[e[i].y]=1;
21             if((!p[e[i].y])||dfs(p[e[i].y])){
22                 p[e[i].y]=x;
23                 return 1;
24             }
25         }
26     }return 0;
27 }
28 int main(){
29     int T;scanf("%d",&T);
30     while(T-->0){
31         scanf("%d%d",&n,&m);
32         memset(p,0,sizeof(p));
33         memset(vis,0,sizeof(vis));
34         memset(head,0,sizeof(head));tot=0;
35         int x,y;
36         for(int i=1;i<=n;i++){
37             scanf("%d",&x);
38             for(int j=1;j<=x;j++){scanf("%d",&y);init(i,y);}
39         }
40         int ans=0;
41         for(int i=1;i<=n;i++){memset(vis,0,sizeof(vis));if(dfs(i))++ans;}
42         if(ans==n)printf("YES\n");
43         else printf("NO\n");
44     }
45     return 0;
46 }
View Code

hopcroft-karp O(sqrt(n)m)

https://blog.csdn.net/wall_f/article/details/8248373

是一种魔改版匈牙利,魔改之后竟然有点像网络流。不过我用网络流找最大匹配差不多也是这个复杂度吧,这个算法有什么意义吗。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<queue>
 7 using namespace std;
 8 #define LL long long
 9 const int maxn=310;
10 const int minf=90000;
11 int n,m,dis;
12 struct nod{
13     int y,next;
14 }e[maxn*100];
15 int head[maxn]={},tot=0;
16 int vis[maxn]={};
17 int cx[maxn]={},cy[maxn]={},dx[maxn]={},dy[maxn]={};
18 inline void init(int x,int y){e[++tot].y=y;e[tot].next=head[x];head[x]=tot;}
19 bool bfs(){
20     memset(dx,-1,sizeof(dx));memset(dy,-1,sizeof(dy));
21     dis=minf;queue<int>q;
22     for(int i=1;i<=n;i++){if(!cx[i]){q.push(i);dx[i]=0;}}
23     while(!q.empty()){
24         int x=q.front();q.pop();
25         if(dx[x]>dis)break;
26         for(int i=head[x];i;i=e[i].next){
27             int y=e[i].y;
28             if(dy[y]==-1){
29                 dy[y]=dx[x]+1;
30                 if(!cy[y])dis=dy[y];
31                 else {dx[cy[y]]=dy[y]+1;q.push(cy[y]);}
32             }
33         }
34     }
35     return dis!=minf;
36 }
37 int dfs(int x){
38     for(int i=head[x];i;i=e[i].next){
39         int y=e[i].y;
40         if((!vis[y])&&dy[y]==dx[x]+1){
41             vis[y]=1;
42             if(cy[y]&&dy[y]==dis)continue;
43             if((!cy[y])||dfs(cy[y])){
44                 cy[y]=x;cx[x]=y;
45                 return 1;
46             }
47         }
48     }
49     return 0;
50 }
51 int main(){
52     int T;scanf("%d",&T);
53     while(T-->0){
54         scanf("%d%d",&n,&m);
55         memset(head,0,sizeof(head));tot=0;
56         int x,y;
57         for(int i=1;i<=n;i++){
58             scanf("%d",&x);
59             for(int j=1;j<=x;j++){scanf("%d",&y);init(i,y);}
60         }
61         int ans=0;
62         memset(cx,0,sizeof(cx));
63         memset(cy,0,sizeof(cy));
64         while(bfs()){
65             memset(vis,0,sizeof(vis));
66             for(int i=1;i<=n;i++){
67                 if(!cx[i])ans+=dfs(i);
68             }
69         }
70         if(ans==n)printf("YES\n");
71         else printf("NO\n");
72     }
73     return 0;
74 }
View Code

 

posted @ 2018-05-30 10:17  鲸头鹳  阅读(136)  评论(0编辑  收藏  举报