poj 2391 (Floyd+最大流+二分)

来源:互联网 发布:linux兄弟连视频 编辑:程序博客网 时间:2024/05/22 07:45

题意:有n块草地,一些奶牛在草地上吃草,草地间有m条路,一些草地上有避雨点,每个避雨点能容纳的奶牛是有限的,给出通过每条路的时间,问最少需要多少时间能让所有奶牛进入一个避雨点。

两个避雨点间可以相互到达,所以必须要拆点,如果i-->j可以到达,加边i->j+n,流量无穷大,当然i->i+n也必须有边,,,

Folyd要用long long,,,,,







#include<stdio.h>#include<string.h>const int N=410;const int inf=0x3fffffff;int gap[N],dis[N],head[N],num,start,end,ans,n;__int64 map[N][N];struct edge{int st,ed,flow,next;}E[90000];struct node{int w1,w2;}P[210];void addedge(int x,int y,int w){E[num].st=x;E[num].ed=y;E[num].flow=w;E[num].next=head[x];head[x]=num++;E[num].st=y;E[num].ed=x;E[num].flow=0;E[num].next=head[y];head[y]=num++;}int dfs(int u,int minflow){if(u==end)return minflow;int i,v,f,flow=0,min_dis=ans-1;for(i=head[u];i!=-1;i=E[i].next){v=E[i].ed;if(E[i].flow>0){if(dis[v]+1==dis[u]){f=dfs(v,E[i].flow>minflow-flow?minflow-flow:E[i].flow);E[i].flow-=f;E[i^1].flow+=f;flow+=f;if(flow==minflow)break;if(dis[start]>=ans)return flow;}min_dis=min_dis>dis[v]?dis[v]:min_dis;}}if(flow==0){if(--gap[dis[u]]==0)dis[start]=ans;dis[u]=min_dis+1;gap[dis[u]]++;}return flow;}int isap(){int maxflow=0;memset(dis,0,sizeof(dis));memset(gap,0,sizeof(gap));gap[0]=ans;while(dis[start]<ans)maxflow+=dfs(start,inf);//printf("maxflow=%d\n",maxflow);return maxflow;}void makemap(__int64 D){memset(head,-1,sizeof(head));num=0;int i,j;for(i=1;i<=n;i++){addedge(i,i+n,inf);addedge(start,i,P[i].w1);for(j=i+1;j<=n;j++){if(map[i][j]<=D){addedge(i,j+n,inf);addedge(j,i+n,inf);}}addedge(i+n,end,P[i].w2);}}int main(){int i,j,k,x,y,w,m,sum;while(scanf("%d%d",&n,&m)!=-1){start=0;end=n*2+1;ans=end+1;sum=0;for(i=1;i<=n;i++){for(j=i+1;j<=n;j++)map[i][j]=map[j][i]=1000000000000;map[i][i]=0;}for(i=1;i<=n;i++){scanf("%d%d",&P[i].w1,&P[i].w2);sum+=P[i].w1;}for(i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&w);if(map[x][y]>w)map[x][y]=map[y][x]=w;}for(k=1;k<=n;k++)for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(map[i][j]>map[i][k]+map[k][j])map[i][j]=map[i][k]+map[k][j];__int64 L,R,mid,flag;L=0;flag=-1;R=0;for(i=1;i<=n;i++)for(j=i+1;j<=n;j++)if(R<map[i][j]&&map[i][j]<1000000000000)R=map[i][j];while(L<=R){mid=(L+R)/2;makemap(mid);//printf("mid=%d\n",mid);if(isap()==sum){flag=mid;R=mid-1;}else L=mid+1;}printf("%I64d\n",flag);}return 0;}






原创粉丝点击