hust 1024(二分+最大流)

hust 1024(二分+最大流)dance party Time Limit 2 Sec Memory Limit 128 MB Submissions 374 Solved 136 Description You are organizing a dance party The party will be attended by n boys and n

大家好,我是讯享网,很高兴认识大家。

dance party

Time Limit: 2 Sec   Memory Limit: 128 MB
Submissions: 374   Solved: 136

Description

You are organizing a dance party. The party will be attended by n boys and n girls. There will be several rounds of dancing.
In each round, you divide the guests into n dancing pairs. Each guest must be in exactly one pair, and each pair must contain one boy and one girl. Each boy must dance with a different girl in every round. Some boys and girls like each other and some do not. During the party, each boy agrees to dance with at most k girls he doesn't like. Similarly, each girl agrees to dance with at most k boys she doesn't like. 
You are given the each pairs of boys and girls who agree to dance with each other .Find out the maximum number of rounds you can organize.

Input

The first line contains a integer t,which means there are t cases followed.
For each case,the first line contain three integer n,m,k ,which means there are n boys and n girls attending the party and m pairs of boys and girls who agree to dance with each other,and each boy or girl agrees to dance with at most k girls or boys he or she doesn't like.At last ,there are m lines with two integers a,b which means boy a and girl b agree to dance with each other.
(0<n<=100,0<m<=n*n,0<k<100,0<a,b<=n)

Output

Sample Input

2 2 4 0 1 1 2 2 2 1 1 2 3 7 0 1 1 1 2 1 3 2 1 2 2 3 1 3 3

讯享网

Sample Output

讯享网2 2

HINT

Source

lshmouse


讯享网

分析:这题可以看成求最多次能做几次二分图完全匹配,即最大流刚好为点的倍数,于是可以二分答案,然后用最大流判断是否可行,关键在于构图:

      二分答案ans;

       将每个男孩看成左边的点X,女孩为右边的点Y,然后将X分为与自己喜欢的跳舞Xa,不喜欢的Xb,Y同分为Ya,Yb,在源点src与所以Xa之间连一条容量为ans的有向边,在Ya与汇点dest之间连一条容量为ans的有向边,在Xa与Xb,Yb与Ya之间连一条有向边,之后在枚举所以男孩i,女孩j,如果i可以和j一起,则在Xai与Yaj之间连一条容量为1的有向边,否则在Xbi与Ybj之间连一条有向边,当前最大流如果为n的倍数及答案ans可行。。。

代码:

#include<cstdio> using namespace std; const int mm=; const int mn=444; const int oo=; int node,src,dest,edge,k,n; int reach[mm],flow[mm],next[mm]; int head[mn],work[mn],dis[mn],q[mn]; bool like[111][111]; inline int min(int a,int b) { return a<b?a:b; } inline void prepare(int _node,int _src,int _dest) { node=_node,src=_src,dest=_dest; for(int i=0; i<node; ++i)head[i]=-1; edge=0; } inline void addedge(int u,int v,int c) { reach[edge]=v,flow[edge]=c,next[edge]=head[u],head[u]=edge++; reach[edge]=u,flow[edge]=0,next[edge]=head[v],head[v]=edge++; } bool Dinic_bfs() { int i,u,v,l,r=0; for(i=0; i<node; ++i)dis[i]=-1; dis[q[r++]=src]=0; for(l=0; l<r; ++l) for(i=head[u=q[l]]; i>=0; i=next[i]) if(flow[i]&&dis[v=reach[i]]<0) { dis[q[r++]=v]=dis[u]+1; if(v==dest)return 1; } return 0; } int Dinic_dfs(int u,int exp) { if(u==dest)return exp; for(int &i=work[u],v,tmp; i>=0; i=next[i]) if(flow[i]&&dis[v=reach[i]]==dis[u]+1&&(tmp=Dinic_dfs(v,min(exp,flow[i])))>0) { flow[i]-=tmp; flow[i^1]+=tmp; return tmp; } return 0; } int Dinic_flow() { int i,ret=0,delta; while(Dinic_bfs()) { for(i=0; i<node; ++i)work[i]=head[i]; while(delta=Dinic_dfs(src,oo))ret+=delta; } return ret; } inline void fresh(int c) { int i,j; for(i=0; i<edge; ++i)flow[i]=((i&1)==0); for(i=1; i<=n; ++i) { flow[head[i]^1]=c; flow[head[i+3*n]]=c; flow[head[i+2*n]]=k; flow[next[head[i]]]=k; } } int main() { int i,j,m,t,l,r; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&k); for(i=1; i<=n; ++i) for(j=1; j<=n; ++j)like[i][j]=0; while(m--)scanf("%d%d",&i,&j),like[i][j]=1; prepare(n*4+2,0,n*4+1); for(i=1; i<=n; ++i) for(j=1; j<=n; ++j) if(like[i][j])addedge(i,j+3*n,0); else addedge(i+n,j+2*n,0); for(i=1; i<=n; ++i) { addedge(i,i+n,0); addedge(i+2*n,i+3*n,0); addedge(src,i,0); addedge(i+3*n,dest,0); } l=0,r=n; while(l<=r) { m=(l+r)>>1; fresh(m); if(Dinic_flow()==n*m)l=m+1; else r=m-1; } printf("%d\n",l-1); } return 0; } 


小讯
上一篇 2025-03-23 19:18
下一篇 2025-01-24 20:00

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/22472.html