poj2112(网络流-最大流+二分)
生活随笔
收集整理的這篇文章主要介紹了
poj2112(网络流-最大流+二分)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:給你k個擠奶器,c頭牛,每個擠奶器能放m頭牛,問你奶牛需要走的最大距離最小是多少;
解題思路:因為最大距離最小,也就是求最小的距離滿足所有牛都能到,所以我們先用floyd跑最短路,把所有點之間的距離算出來后再,對答案進行二分:牛和擠奶器的距離<=二分值的可以連一條邊,容量為1;
然后源點和奶牛連一條容量為1的邊,擠奶器和匯點連一條容量為m的邊,所以二分只是為了看奶牛是否能到達某個擠奶器;
代碼:
#include<iostream> #include<algorithm> #include<cstring> #include<queue> #include<cstdio> #define maxn 100500 #define inf 0x3f3f3f3f using namespace std; struct Edge {int next;int to;int w;int fa; }edge[maxn]; int head[maxn]; int x,y; int dist[505][505]; int cnt; int n,m,Start,End; int k,c; int depth[maxn]; void floyd() {for(int l=1;l<=c+k;l++){for(int i=1;i<=c+k;i++){for(int j=1;j<=c+k;j++){if(dist[i][j]>dist[i][l]+dist[l][j])dist[i][j]=dist[i][l]+dist[l][j];}}} } void add(int u,int v,int w) {edge[cnt].next=head[u];edge[cnt].to=v;edge[cnt].fa=u;edge[cnt].w=w;head[u]=cnt++;edge[cnt].next=head[v];edge[cnt].w=0;edge[cnt].to=u;edge[cnt].fa=v;head[v]=cnt++; } bool bfs() {memset(depth,0,sizeof(depth));queue<int>q;q.push(Start);depth[Start]=1;while(!q.empty()){int u=q.front();q.pop();for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;if(depth[v]||edge[i].w<=0)continue;depth[v]=depth[u]+1;q.push(v);}}return depth[End]; } int dfs(int u,int maxflow) {if(u==End)return maxflow;int add=0;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;if(depth[v]!=depth[u]+1)continue;if(edge[i].w==0)continue;int tempflow=dfs(v,min(edge[i].w,maxflow-add));edge[i].w-=tempflow;edge[i^1].w+=tempflow;add+=tempflow;}return add; } int dinic() {int ans=0;while(bfs()){ans+=dfs(Start,inf);}return ans; } void buildmap(int value) {memset(head ,-1,sizeof(head));cnt=0;for(int i=k+1;i<=k+c;i++){add(0,i,1);}for(int i=k+1;i<=k+c;i++){for(int j=1;j<=k;j++){if(dist[i][j]<=value){add(i,j,1);// cout<<i<<" "<<j<<endl;}}}for(int i=1;i<=k;i++){add(i,k+c+1,m);} } int main() {scanf("%d%d%d",&k,&c,&m);Start=0;End=k+c+1;for(int i=1;i<=k+c;i++){for(int j=1;j<=k+c;j++){scanf("%d",&dist[i][j]);if(dist[i][j]==0)dist[i][j]=inf;}}floyd();int l=0,r=10000;while(l<r){int mid=(l+r)/2;buildmap(mid);int xx=dinic();if(xx>=c){r=mid;}else{l=mid+1;}}printf("%d\n",r); }
轉載于:https://www.cnblogs.com/huangdao/p/9304470.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的poj2112(网络流-最大流+二分)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [名词解释] intuitive
- 下一篇: .Net Core Cors中间件解析