poj 2112 网络流

来源:互联网 发布:移动网络线路转换器 编辑:程序博客网 时间:2024/04/30 23:13

完全不会。。看了好久别人的代码 才看懂。

建图:vs=0 ve=k+c+1 从Vs到奶牛边权值为1,机器到ve权值为M。奶牛到机器权值为1.

利用二分思想,从某长开始构图,把小于等于此长的边留下,再来bfs看看能不能形成增广路,能的话dfs一下返回流量,若返回的流量>=C证明此长可以,那么减小长度接着构图、bfs、dfs。


#include<stdio.h>#include<string.h>#define MX 10000000int q[1000000],vst[400],n,dis[500][500],map[400][400],sign[400][400],K,C,M;void build_graph(int mid){memset(map,0,sizeof(map));for(int i=1+K;i<n;i++)for(int j=1;j<=K;j++)if(dis[i][j]<=mid)map[i][j]=1;for(int i=K+1;i<n;i++)map[0][i]=1;for(int i=1;i<=K;i++)map[i][n]=M;}bool bfs(){memset(sign,0,sizeof(sign));memset(vst,0,sizeof(vst));int qs=0,qe=1;q[qs]=0;vst[0]=1;while(qs<qe){int v=q[qs++];for(int i=0;i<=n;i++)if(!vst[i]&&map[v][i]){sign[v][i]=1;vst[i]=1;q[qe++]=i;}}if(!vst[n])return false;else return true;}int dfs(int v,int num){int num1=num;if(v==n) return num;elsefor(int i=0;i<=n;i++)if(sign[v][i]){int min=num<map[v][i]?num:map[v][i];int t=dfs(i,min);map[v][i]-=t;map[i][v]+=t;num-=t;}return num1-num;}int main(){while(scanf("%d%d%d",&K,&C,&M)!=EOF){n=K+C+1;for(int i=1;i<n;i++)for(int j=1;j<n;j++){scanf("%d",&dis[i][j]);if(dis[i][j]==0)dis[i][j]=MX;}for(int k=1;k<n;k++)for(int i=1;i<n;i++){if(dis[i][k]<MX)for(int j=1;j<n;j++)if(dis[i][k]+dis[k][j]<dis[i][j])dis[i][j]=dis[i][k]+dis[k][j];}int l=0,r=10000;while(l<r){int mid=(r+l)/2,ans=0;build_graph(mid);while(bfs()){ans+=dfs(0,MX);}if(ans>=C)r=mid;elsel=mid+1;}printf("%d\n",r);}return 0;}


原创粉丝点击