日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

【HDU - 3081】Marriage Match II(网络流最大流,二分+网络流)

發(fā)布時(shí)間:2023/12/10 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【HDU - 3081】Marriage Match II(网络流最大流,二分+网络流) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題干:

Presumably, you all have known the question of stable marriage match. A girl will choose a boy; it is similar as the game of playing house we used to play when we are kids. What a happy time as so many friends playing together. And it is normal that a fight or a quarrel breaks out, but we will still play together after that, because we are kids.?
Now, there are 2n kids, n boys numbered from 1 to n, and n girls numbered from 1 to n. you know, ladies first. So, every girl can choose a boy first, with whom she has not quarreled, to make up a family. Besides, the girl X can also choose boy Z to be her boyfriend when her friend, girl Y has not quarreled with him. Furthermore, the friendship is mutual, which means a and c are friends provided that a and b are friends and b and c are friend.?
Once every girl finds their boyfriends they will start a new round of this game—marriage match. At the end of each round, every girl will start to find a new boyfriend, who she has not chosen before. So the game goes on and on.?
Now, here is the question for you, how many rounds can these 2n kids totally play this game??

Input

There are several test cases. First is a integer T, means the number of test cases.?
Each test case starts with three integer n, m and f in a line (3<=n<=100,0<m<n*n,0<=f<n). n means there are 2*n children, n girls(number from 1 to n) and n boys(number from 1 to n).?
Then m lines follow. Each line contains two numbers a and b, means girl a and boy b had never quarreled with each other.?
Then f lines follow. Each line contains two numbers c and d, means girl c and girl d are good friends.?

Output

For each case, output a number in one line. The maximal number of Marriage Match the children can play.

Sample Input

1 4 5 2 1 1 2 3 3 2 4 2 4 4 1 4 2 3

Sample Output

2

題目大意:

n個(gè)女生與n個(gè)男生配對(duì),每個(gè)女生只能配對(duì)某些男生,有些女生相互是朋友,每個(gè)女生也可以跟她朋友能配對(duì)的男生配對(duì)。

每次配對(duì),每個(gè)女生都要跟不同的男生配對(duì)且每個(gè)女生都能配到對(duì)。問(wèn)最多能配對(duì)幾輪。

解題報(bào)告:(貼一個(gè)題解鏈接)

考慮用網(wǎng)絡(luò)流做,首先女生可以與她朋友能配對(duì)的男生配對(duì),這樣需要用并查集保存他們可以配對(duì)的關(guān)系。

為了保證每一輪所有女生和男生都能匹配到,我們需要二分源點(diǎn)和女生、男生和匯點(diǎn)之間的容量k,并且需要保證滿流。找到最大的滿足條件的k就是答案。

解法的正確性可以用數(shù)學(xué)歸納法證明,當(dāng)k=1時(shí),轉(zhuǎn)化為一個(gè)二分匹配,如果滿流,就說(shuō)明可以進(jìn)行一輪。當(dāng)k-1輪可以實(shí)現(xiàn)時(shí)(k-1滿流),如果容量為k時(shí)滿流,說(shuō)明也可以實(shí)現(xiàn)k輪。這樣就證明了正確性。

由這個(gè)解法我們也可以想到用二分匹配的方法來(lái)解決:進(jìn)行二分圖的最大匹配,在匹配完成后判斷匹配數(shù)是否等于n,不是的話說(shuō)明GAME OVER 求得答案,是的話說(shuō)明游戲能完成,然后進(jìn)行刪邊操作,再繼續(xù)匹配,直到匹配數(shù)<n則得到答案。

AC代碼:

#include<cstring> #include<cstdio> #include<algorithm> #include<iostream> #include<set> using namespace std; const int INF = 0x3f3f3f3f; int tot; struct Edge {int to,ne,w; } e[1000005 * 2]; int head[10005]; int st,ed; int dis[10050],q[10005];//一共多少個(gè)點(diǎn)跑bfs,dis數(shù)組和q數(shù)組就開(kāi)多大。 void add(int u,int v,int w) {e[++tot].to=v; e[tot].w=w; e[tot].ne=head[u]; head[u]=tot;e[++tot].to=u; e[tot].w=0; e[tot].ne=head[v]; head[v]=tot; } bool bfs(int st,int ed) {memset(dis,-1,sizeof(dis));int front=0,tail=0;q[tail++]=st;dis[st]=0;while(front<tail) {int cur = q[front];if(cur == ed) return 1;front++;for(int i = head[cur]; i!=-1; i = e[i].ne) {if(e[i].w&&dis[e[i].to]<0) {q[tail++]=e[i].to;dis[e[i].to]=dis[cur]+1;}}}if(dis[ed]==-1) return 0;return 1; } int dfs(int cur,int limit) {//limit為源點(diǎn)到這個(gè)點(diǎn)的路徑上的最小邊權(quán) if(limit==0||cur==ed) return limit;int w,flow=0;for(int i = head[cur]; i!=-1; i = e[i].ne) { if(e[i].w&&dis[e[i].to]==dis[cur]+1) {w=dfs(e[i].to,min(limit,e[i].w));e[i].w-=w;e[i^1].w+=w;flow+=w;limit-=w;if(limit==0) break;}}if(!flow) dis[cur]=-1;return flow; } int dinic() {int ans = 0;while(bfs(st,ed)) ans+=dfs(st,0x7fffffff);return ans; } int v[100005],u[100005],n,m,f; int fa[100005]; bool has[555][555]; int getf(int v) {return fa[v] == v ? v : fa[v] = getf(fa[v]); } bool ok(int x) {//每次都要重新建圖 tot=1;memset(head,-1,sizeof head);for(int i = 1; i<=n; i++) add(st,i,x);for(int i = 1; i<=n; i++) add(n+i,ed,x);//設(shè)為INF也可以??答:并不可以 // for(int i = 1; i<=m; i++) add(u[i],n+v[i],1);for(int i = 1; i<=n; i++) {for(int j = 1; j<=n; j++) if(has[i][j]) add(i,j+n,1);}int ans = dinic();if(x*n == ans) return 1;else return 0; } int main() {int t;cin>>t;while(t--) {scanf("%d%d%d",&n,&m,&f);memset(has,0,sizeof has);for(int i = 1; i<=n; i++) fa[i]=i;st=2*n+1,ed=st+1;for(int i = 1; i<=m; i++) {//u女v男 scanf("%d%d",u+i,v+i);has[u[i]][v[i]]=1;}for(int u,v,i = 1; i<=f; i++) {//f對(duì)女生 scanf("%d%d",&u,&v);u=getf(u),v=getf(v);fa[u]=v;}for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)if(getf(i)==getf(j))for(int k=1;k<=n;++k)if(has[i][k])has[j][k]=1;int l = 0,r = n,mid,ans=0;while(l<=r) {mid=(l+r)>>1;if(ok(mid)) l=mid+1,ans=mid;else r = mid-1;}printf("%d\n",ans); }return 0; }

總結(jié):

錯(cuò)誤想法1:S-Girl和Boy-T設(shè)成INF,然后跑一次最大流,然后答案為S-Girl和Boy-T的邊中流量的最小值,為什么不行。

給一組樣例:

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

答案應(yīng)該是0,但用上述方法答案為1。

錯(cuò)誤想法2:

考慮到n個(gè)女生和n個(gè)男生不重復(fù)完全配對(duì)最多只能進(jìn)行n輪,想到可以將源點(diǎn)和女生、男生和匯點(diǎn)之間的容量賦為n,求出最大流。但是發(fā)現(xiàn)這樣是不行的,如果有女生或者男生一直無(wú)法配對(duì),則答案本應(yīng)是0,但是最大流肯定是>0的,所以答案是不對(duì)的。這個(gè)想法錯(cuò)就錯(cuò)在沒(méi)有抓住那個(gè)關(guān)鍵點(diǎn):每一次舞會(huì)一定是男生女生全員參與,也就是抽象成:女生這邊都流出1的流量總有所有的男生全部接受到,也就是男生這邊接收到的流量總是等量的,不能是:1號(hào)男生接受到2流量,2號(hào)男生沒(méi)有流量流過(guò)。

錯(cuò)誤想法3:

為什么不能直接把男生和匯點(diǎn)的流量設(shè)置為INF?

答:這也是和錯(cuò)誤想法2差不多相同的錯(cuò)誤。你這樣沒(méi)法保證每個(gè)男生接受的流量總是等量的。

?

本來(lái)想著是把左側(cè)的點(diǎn)再拆成n個(gè)點(diǎn),然后對(duì)應(yīng)連到右邊,后來(lái)發(fā)現(xiàn)沒(méi)啥意義,可以直接連到右邊的。

不過(guò)本來(lái)還有個(gè)想法,那就是把她和她的朋友關(guān)系直接轉(zhuǎn)化到左邊的點(diǎn)(女生之間的點(diǎn))相連,而不直接轉(zhuǎn)化到和男生的對(duì)應(yīng)關(guān)系,但是后來(lái)發(fā)現(xiàn)這樣是不行的,因?yàn)槟氵@樣沒(méi)法控制每一輪,每個(gè)女生只能和一個(gè)男生建立關(guān)系,因?yàn)槟氵@樣相當(dāng)于把她倆女生當(dāng)成一個(gè)完全一致的物品去看待了,但是其實(shí)她倆肯定是有區(qū)別的。

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的【HDU - 3081】Marriage Match II(网络流最大流,二分+网络流)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。