HUST [1024] dance party &&HDU Marriage Match II &&HDU Marriage Match III

http://acm.hust.edu.cn/thx/problem.php?id=1024 Accepted

http://acm.hdu.edu.cn/showproblem.php?pid=3081 Accepted

http://acm.hdu.edu.cn/showproblem.php?pid=3277 很诡异的 wa了。。。20次了。。。

题目大意:n个男孩和n个女孩配对跳舞,要求每一对必须由一男一女组成,n个男孩和n个女孩有他们各自的喜欢的人,每一轮配对都必须和不同的人配对,并且每个人最多和他不喜欢的K个人配对,问:最多能进行多少轮。

算法:二分 + 最大流;

显然每次配对就是一个完全二分匹配,要求这样的二分匹配能进行多少轮,我们要非常迅速的想到转化成最大流,虽然我不知道这是为什么,但是都是这么做;

然后拆点,男1和他喜欢的女1连边长为1的边,男1和男2连边长为k的边,男2和他不喜欢的女2连边长为1的边,女1和女2连边长为k的边,然后最大流,若最大流 = mid*n 表明能mid个环能构成;继续二分;

开始有一个小小的地方wa了,以为是算法分析错了,想去网上找段AC代码来对拍,悲剧网上面没搜的到。。。。只好自己慢慢找,无意之间改了下下面的数字,居然能够AC。。。

代码:

 #include<string.h> #include<stdio.h> const int N = 511 ; int n,m,k,s,t,map[N][N],ral[N][N]; void bulid(int flow) { for(int i=1;i<=n;i++) { map[s][i] = flow ; map[3*n+i][t] = flow ; } for(int i=0;i<=t;i++) { for(int j=0;j<=t;j++) { ral[i][j] = map[i][j] ; } } } int maxf(int aug,int flow) { if(aug==-1||flow<aug) return flow ; return aug ; } int sap() { int u,aug=-1,maxflow=0,pre[N],gap[N],dis[N] ; memset(gap,0,sizeof(gap)) ; memset(dis,0,sizeof(dis)) ; u=pre[s]=s; gap[0]=t-1; while(dis[s]<t) { loop: for(int i=1;i<=t;i++) { if(ral[u][i]&&dis[u]==dis[i]+1) { aug = maxf(aug,ral[u][i]) ; pre[i] = u ; u = i ; if(u==t) { maxflow += aug; for(int v=u;v!=s;v=pre[v]) { ral[pre[v]][v] -= aug ; ral[v][pre[v]] += aug ; } u = s ; aug = -1 ; } goto loop ; } } int mindis=t-1 ; for(int i=1;i<=t;i++) if(ral[u][i]&&dis[i]<mindis) mindis = dis[i] ; if((--gap[dis[u]])==0) break ; gap[dis[u] = mindis + 1]++ ; u = pre[u] ; } return maxflow ; } int main() { int cas ; scanf("%d",&cas) ; while(cas--) { scanf("%d%d%d",&n,&m,&k) ; memset(map,0,sizeof(map)) ; int from,to; while(m--) { scanf("%d%d",&from,&to) ; map[from][3*n+to] = 1 ; map[from][n+from] = k ; map[2*n+to][3*n+to] = k ; } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(map[i][3*n+j]==0) map[n+i][2*n+j] = 1 ; } } s = 4*n+2,t=4*n+3 ;//怪异的地方 。。。。。 why s = 4*n+1,t=4*n+2 is wrong anwser ? int mid , left = 0 , right = n ; while(left<=right) { mid = (left+right)/2 ; bulid(mid) ; if(sap()==mid*n) left = mid + 1 ; else right = mid - 1 ; } printf("%d/n",right) ; } return 0 ; }

 

你可能感兴趣的:(HUST [1024] dance party &&HDU Marriage Match II &&HDU Marriage Match III)