日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UVa10779 - Collectors Problem(最大流)

發布時間:2023/12/2 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UVa10779 - Collectors Problem(最大流) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接

簡介:交換貼紙

分析:
這也算是一個天坑了
很久之前就看過這道題,但是一直沒有填

美妙的建圖:
我們用n-1個點表示每個除Bob之外的人
用m個點表示貼紙,從源點向這m個點連邊,邊的容量是Bob擁有該種貼紙的數量

接下來我們要連接其他人和貼紙:
如果第i個人有超過一張j種貼紙(有k張),那么我們就連接i—>j,容量為k-1,表示ta可以貢獻出k-1張第j種貼紙
如果第i個人沒有第j種貼紙,那么我們連接j—>i,容量為1,表示ta最多接受一張j貼紙

最后所有的貼紙連向匯點,流量為1

最大流即為最后答案

附樣例圖:

//這里寫代碼片 #include<cstdio> #include<cstring> #include<iostream> #include<queue>using namespace std;const int N=101; const int INF=0x33333333; struct node{int x,y,v,nxt; }; node way[N*N]; int st[N],tot,deep[N],cur[N],s,t; int n,m,zl[30][30];void add(int u,int w,int z) {tot++;way[tot].x=u;way[tot].y=w;way[tot].v=z;way[tot].nxt=st[u];st[u]=tot;tot++;way[tot].x=w;way[tot].y=u;way[tot].v=0;way[tot].nxt=st[w];st[w]=tot; }int bfs(int s,int t) {for (int i=s;i<=t;i++) cur[i]=st[i];memset(deep,-1,sizeof(deep));queue<int> Q;Q.push(s);deep[s]=1;while (!Q.empty()){int now=Q.front(); Q.pop();for (int i=st[now];i!=-1;i=way[i].nxt)if (way[i].v&&deep[way[i].y]==-1){deep[way[i].y]=deep[now]+1;Q.push(way[i].y);}}return deep[t]!=-1; }int dfs(int now,int t,int limit) {if (now==t||!limit) return limit;int f,flow=0;for (int i=cur[now];i!=-1;i=way[i].nxt){cur[now]=i;if (way[i].v&&deep[way[i].y]==deep[now]+1&&(f=dfs(way[i].y,t,min(limit,way[i].v)))){flow+=f;limit-=f;way[i].v-=f;way[i^1].v+=f;if (!limit) break;}}return flow; }int dinic() {int ans=0;while (bfs(s,t))ans+=dfs(s,t,INF);return ans; }int main() {int T;scanf("%d",&T);for (int cas=1;cas<=T;cas++){memset(st,-1,sizeof(st));tot=-1;scanf("%d%d",&n,&m);memset(zl,0,sizeof(zl));for (int i=1;i<=n;i++){ int k,x; //inputscanf("%d",&k);for (int l=1;l<=k;l++)scanf("%d",&x),zl[i][x]++;}s=0; t=n+m+1;for (int i=1;i<=m;i++){if (zl[1][i]) add(s,i,zl[1][i]);add(i,t,1);} for (int i=2;i<=n;i++)for (int j=1;j<=m;j++){if (zl[i][j]>1) //可以給出一張j add(i+m,j,zl[i][j]-1);if (!zl[i][j]) //沒有j,最多可以接受一張j add(j,i+m,1);}printf("Case #%d: %d\n",cas,dinic());} return 0; }

轉載于:https://www.cnblogs.com/wutongtong3117/p/7673029.html

總結

以上是生活随笔為你收集整理的UVa10779 - Collectors Problem(最大流)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。