sgu 242 Student's Morning--最大流 或 多重匹配
来源:互联网 发布:阿里云待遇 编辑:程序博客网 时间:2024/05/01 21:57
/*n同学分别来自不同的学校,他们想去学校玩,但是不像一个人去,所以去某个学校的人数应>=2问是否有k个学校满足要求建边:[s,学校] 权为2[学校,同学] 权为1[同学,t] 权为1据说这题可以用匹配做,以后看看*/#include<stdio.h>#include<string.h>#define inf 0x7ffffffstruct edge{int u,v,f,next;}e[100010];int head[410],yong;int n,k,s,t;void ini(){memset(head,-1,sizeof(head));yong=0;s=0,t=2*n+1;}void adde(int from,int to,int flow){e[yong].u=from,e[yong].v=to,e[yong].f=flow;e[yong].next=head[from],head[from]=yong++;e[yong].u=to,e[yong].v=from,e[yong].f=0;e[yong].next=head[to],head[to]=yong++;}int d[410],num[410]; int min(int a,int b){return a<b?a:b;} int sap_gap(int u,int f,int s,int t){ if(u==t) return f; int i,v,mind=t,last=f,cost; for(i=head[u];i!=-1;i=e[i].next) { v=e[i].v; int flow=e[i].f; if(flow>0) { if(d[u]==d[v]+1) { cost=sap_gap(v,min(last,flow),s,t); e[i].f-=cost; e[i^1].f+=cost; last-=cost; if(d[s]>=t+1) return f-last; if(last==0) break; } if(d[v]<mind) mind=d[v]; } } if(last==f) { --num[d[u]]; if(num[d[u]]==0) d[s]=t+1; d[u]=mind+1; ++num[d[u]]; } return f-last; } int max_f(int s,int t) { int f=0; memset(d,0,sizeof(d)); memset(num,0,sizeof(num)); for(num[s]=t+1;d[s]<t+1;) f+=sap_gap(s,inf,s,t); return f; } int main(){int i,nn,j,a;while(scanf("%d%d",&n,&k)!=EOF){ini();for(i=1;i<=n;++i){scanf("%d",&nn);while(nn--){scanf("%d",&a);adde(a,n+i,1);}}for(i=1;i<=n;i++)adde(s,i,2);for(i=n+1;i<=n+n;i++)adde(i,t,1);j=max_f(s,t);if(j<k*2)printf("NO\n");else{printf("YES\n");i=1;while(k--){printf("2 ");j=head[i];while(e[j].f!=0) j=e[j].next;printf("%d ",e[j].v-n);j=e[j].next;while(e[j].f!=0) j=e[j].next;printf("%d\n",e[j].v-n);i++;}}}return 0;}
写了两种多重匹配:1.拆点2.用结构体表示多重匹配点
前者适用于所有点的多重匹配数量相同
后者没什么限制
/*用多重匹配写的把每个学校拆成两个点 然后匹配*/#include<iostream>using namespace std;int n,k;int map[210][410];int match[410],vis[410];int dfs(int i){int j;for(j=0;j<k*2;++j){if(!vis[j]&&map[i][j])//忘了写后面这个条件{vis[j]=1;if(match[j]==-1||dfs(match[j])){match[j]=i;return 1;}}}return 0;}int main(){int i,nn,j,a;while(cin>>n>>k){memset(map,0,sizeof(map));for(i=0;i<n;++i){cin>>nn;while(nn--){cin>>a;map[i][(a-1)*2]=1;map[i][(a-1)*2+1]=1;}}a=0;memset(match,-1,sizeof(match));for(i=0;i<n;++i){memset(vis,0,sizeof(vis));if(dfs(i))a++;}if(a==2*k){cout<<"YES"<<endl;for(i=0;k;){if(match[i]!=-1&&match[i+1]!=-1){cout<<"2 "<<(match[i]+1)<<" "<<(match[i+1]+1)<<endl;k--;}i=i+2;}}else cout<<"NO"<<endl;}return 0;}
/*用多重匹配写的每个学校是一个结构体,里边保存匹配信息对应普通匹配的 if(match[j]==-1||dfs(match[j]))多重匹配则是 if(匹配还未用完) 匹配成功 相当于match[j]==-1else 尝试替换某个匹配 相当于dfs(match[j])*/#include<iostream>#include<vector>using namespace std;int n,k;int map[210][210],vis[210];struct node{int n;vector<int>match;}school[210];int dfs(int i){int j,k;for(j=0;j<n;++j){if(!vis[j]&&map[i][j]){vis[j]=1;if(school[j].n>0){--school[j].n;school[j].match.push_back(i);return 1;}for(k=0;k<school[j].match.size();++k){if(dfs(school[j].match[k])){school[j].match[k]=i;return 1;}}}}return 0;}int main(){int i,nn,j,a;while(cin>>n>>k){for(i=0;i<n;++i){school[i].n=2;school[i].match.clear();}memset(map,0,sizeof(map));for(i=0;i<n;++i){cin>>nn;while(nn--){cin>>a;map[i][a-1]=1;}}a=0;for(i=0;i<n;++i){memset(vis,0,sizeof(vis));if(dfs(i))a++;}if(a==2*k){cout<<"YES"<<endl;for(i=0;k;){if(school[i].n==0){cout<<"2 "<<(school[i].match[0]+1)<<" "<<(school[i].match[1]+1)<<endl;k--;}++i;}}else cout<<"NO"<<endl;}return 0;}
- sgu 242 Student's Morning--最大流 或 多重匹配
- sgu-242 Student's Morning
- SGU 242 Student's Morning 网络流(水
- SGU 242. Student's Morning
- sgu242:Student's Morning(网络流)
- POJ1698_Alice's Chance(二分图多重最大匹配/最大流)
- hdu 3605 (二分图多重匹配或最大流)
- 解题报告 之 SGU242 Student's Morning
- 网络流 -- Alice's Chance(二分图多重最大匹配/最大流)
- POJ 1698 Alice's Chance 二分图多重匹配 网络最大流
- poj 3189(最大流解决多重匹配)
- POJ2584_T-Shirt Gumbo(二分图多重最大匹配/最大流)
- POJ 2289--Jamie's Contact Groups【二分图多重匹配问题 &&二分查找最大值的最小化 && 最大流求解】
- HDU 3605(多重最大匹配)
- Alice's Chance【多重匹配】
- SGU 326 最大流
- hdu 1669 Jamie's Contact Groups(二分+二分图最大多重匹配)
- Poj 2112 [最大流] [二分图的多重匹配]
- ffmpeg教程三 —— 使用
- 深入探讨MFC消息循环和消息泵
- java switch的使用+switch用String作为条件
- android 进程通信aidl
- 完善匹配中文的Php正则表达式
- sgu 242 Student's Morning--最大流 或 多重匹配
- lamp 李强强特级教程 视频教程 第一集 网站大访问量 服务器集群 负载均衡 PHP 笔记心得
- 写了个android下的计算器,贴贴源码
- Android——Bitmapfactory.options
- Java面向对象总结(基础篇)(草稿)
- ffmpeg教程四 —— 选项详解
- Opencv与VC6.0环境的配置
- 自己写的归并排序 很烂,不过 调试成功了
- Linux下的代码量计算