HDU3081Marriage Match II
来源:互联网 发布:数控切割机用u盘编程 编辑:程序博客网 时间:2024/06/14 11:11
HDU3081Marriage Match II
问题简述:
女生和男生配对,有些女生相互是朋友,每个女生也可以跟她朋友所配对的男生配对每次配对,每个女生都要跟不同的男生配对。问最多能配对几轮。
算法:二分+最大流,用并floyed处理女生之间的朋友关系,最少配0轮,最多配n轮,二分解之,源点向女生建边,男生向汇点建边,容量均为mid,女生跟所有能配对的男生连线,容量为1,如果最大流 = mid * n,就满足条件
#include <cstdio>#include <cstdlib>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#define Inf 0x7fffffffusing namespace std;struct node{ int v,w,next;}t[50010];int g[110][110],c[110][110],tu[110][110];int st,ed,m,n,len,f;int dis[220],cur[220],head[220],gap[220],pre[220];void build(){ int i,j,k; for (k=1; k<=n; k++) for (i=1; i<=n; i++) for (j=1; j<=n; j++) if (!tu[i][j]) tu[i][j]= ( tu[i][k]&&tu[k][j] ); for (i=1; i<=n; i++) for (j=1; j<=n; j++) { c[i][j]=g[i][j]; if (!c[i][j]) for (k=1; k<=n; k++) if (tu[i][k] && g[k][j]) { c[i][j]=1; break; } }}int Isap(){ int flow=0,i,d=Inf,u; bool flag=0; for (i=0; i<=ed; i++) { dis[i]=gap[i]=0; cur[i]=head[i]; } gap[st]=ed+1; u=pre[st]=st; while (dis[st]<ed+1) { flag=0;// wrong printf("%d\n",dis[st]); for (int &j=cur[u]; j!=-1; j=t[j].next) { int v=t[j].v; if (t[j].w>0 && dis[v]+1==dis[u]) { d=min(d,t[j].w); flag=true; pre[v]=u; u=v; if (u==ed) { flow+=d; while (u!=st) { u=pre[u]; t[cur[u]].w-=d; t[cur[u]^1].w+=d; } d=Inf; } break; } } //printf("v==%d\n",u); if (flag) continue; int minh=ed+1; for (int j=head[u]; j!=-1; j=t[j].next) { int v=t[j].v; if (t[j].w>0 && dis[v]<minh) { minh=dis[v]; cur[u]=j; } } if ((--gap[dis[u]])==0) break; dis[u]=minh+1; gap[dis[u]]++; u=pre[u]; } return flow;}void add(int x,int y,int w){ t[len].w=w; t[len].v=y; t[len].next=head[x]; head[x]=len++;}bool check(int k){ int i,j; if (k==0) return true; len=0; memset(head,-1,sizeof(head)); for (i=1; i<=n; i++) { add(st,i,k); add(i,st,0); } for (i=1; i<=n; i++) for (j=1; j<=n; j++) if (c[i][j]) { add(i,n+j,1); add(n+j,i,0); } for (i=n+1; i<=2*n; i++) { add(i,ed,k); add(ed,i,0); } int ans=Isap(); if (ans==n*k) return true; else return false;}void getans(){ int l=0,r=n; while (r-l>=2) { int mid=(l+r)/2; if (check(mid)) l=mid; else r=mid; //printf("%d %d\n",l,r); } for (int i=r; i>=l; i--) if (i<=n && i>=0) if (check(i)) { printf("%d\n",i); return ; }}int main(){ int T,i,j,a,b; freopen("1.in","r",stdin); scanf("%d",&T); while (T--) { scanf("%d%d%d",&n,&m,&f); memset(g,0,sizeof(g)); memset(tu,0,sizeof(tu));//³õʼ»¯´íÁË st=0,ed=2*n+1; len=0; for (i=1; i<=m; i++) { scanf("%d%d",&a,&b); g[a][b]=1; } for (i=1; i<=f; i++) { scanf("%d%d",&a,&b); tu[a][b]=1; tu[b][a]=1; } build(); getans(); } return 0;}
1 0
- HDU3081Marriage Match II
- HDU3081Marriage Match II(二分答案+并查集+最大流SAP)经典
- hdu3081 Marriage Match II
- hdu3081 Marriage Match II
- hdu3081 Marriage Match II
- Marriage Match II HDU
- HDU 3081 Marriage Match II
- HDU 3081 Marriage Match II
- hdu 3081 Marriage Match II
- HDU-3081-Marriage Match II
- HDU 3081 Marriage Match II
- HDU 3081 Marriage Match II
- hdu 3081 Marriage Match II
- HDU-3081 Marriage Match II
- 【HDU】3081 Marriage Match II
- HDU 3081 Marriage Match II
- 【网络流】hdu3081 Marriage Match II
- HDU3081 Marriage Match II 【最大匹配】
- 用Arduino对Apple手表进行远程红外控制
- 1/4波长天线详解
- Qt笔记一
- 课程笔记 03 :数据结构(清华) 向量
- [ASP.NET MVC 大牛之路]01 - C#高级知识点概要(1) - 委托和事件
- HDU3081Marriage Match II
- Java线程中sleep(),wait(),notifyAll()的区别
- 南阳 oj 拦截导弹 求单调递减公共子序列
- java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoader
- 课程设计——简单银行储蓄系统
- Spark入门--实战操作搜狗日志文件
- C++类、结构对象内存布局浅析
- Android中Listview(七)--排序ListView
- Linux驱动开发必看-Linux启动过程(转)