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 "); 43 else printf("NO "); 44 } 45 return 0; 46 }
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 "); 71 else printf("NO "); 72 } 73 return 0; 74 }