poj 2391 floyd+二分+最大流

来源:互联网 发布:java base64解密 编辑:程序博客网 时间:2024/05/22 02:08
/*题意:有n块草地,一些奶牛在草地上吃草,草地间有m条路,一些草地上有避雨点,每个避雨点能容纳的奶牛是有限的,给出通过每条路的时间,问最少需要多少时间能让所有奶牛进入一个避雨点。*/#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <algorithm>using namespace std;#define M 41000const int inf=0x3f3f3f3f;const __int64 maxn =0x3f3f3f3f3f3f3f3fLL;int gap[M],dis[M],pre[M],cur[M];int NE,NV,sink,source;int head[M],n,p,cow[202],sh[202],sum;__int64 d[402][402],ans,c,l,r;struct Node{    int c,pos,next;} E[999999];#define FF(i,NV) for(int i=0;i<NV;i++)int sap(int s,int t){    //memset(pre,-1,sizeof(pre));    memset(dis,0,sizeof(int)*(NV+1));    memset(gap,0,sizeof(int)*(NV+1));    FF(i,NV) cur[i] = head[i];    int u = pre[s] = s,maxflow = 0,aug = inf;    gap[0] = NV;    while(dis[s] < NV)    {loop:        for(int &i = cur[u]; i != -1; i = E[i].next)        {            int v = E[i].pos;            if(E[i].c && dis[u] == dis[v] + 1)            {                aug=min(aug,E[i].c);                pre[v] = u;                u = v;                if(v == t)                {                    maxflow += aug;                   // cout<<maxflow<<endl;                    for(u = pre[u]; v != s; v = u,u = pre[u])                    {                        E[cur[u]].c -= aug;                        E[cur[u]^1].c += aug;                    }                    aug = inf;                }                goto loop;            }        }        int mindis = NV;        for(int i = head[u]; i != -1 ; i = E[i].next)        {            int v = E[i].pos;            if(E[i].c && mindis > dis[v])            {                cur[u] = i;                mindis = dis[v];            }        }        if( (--gap[dis[u]]) == 0)break;        gap[ dis[u] = mindis+1 ] ++;        u = pre[u];    }    return maxflow;}void addEdge(int u,int v,int c ){    E[NE].c = c;    E[NE].pos = v;    E[NE].next = head[u];    head[u] = NE++;    E[NE].c = 0;    E[NE].pos = u;    E[NE].next = head[v];    head[v] = NE++;}void floyd(){    int i,j,k;    for(k=1; k<=n; k++)    {        for(i=1; i<=n; i++)        {            if(d[i][k]!=maxn)                for(j=1; j<=n; j++)                {                    if(d[k][j]!=maxn&&i!=j&&d[i][j]>d[i][k]+d[k][j])                    {                        d[i][j]=d[i][k]+d[k][j];                    }                }        }    }}int ok(__int64 mid){    int i,j;    NE=0;    memset(head,-1,sizeof(int)*(NV+1));    for(i=1;i<=n;i++)    {        addEdge(source,i,cow[i]);        addEdge(i+n,sink,sh[i]);        addEdge(i,i+n,inf);    }    for(i=1;i<=n;i++)    {        for(j=1;j<=n;j++)        {            if(i!=j&&d[i][j]<=mid)            {                addEdge(i,j+n,inf);            }        }    }    int ret=sap(source,sink);    if(ret==sum) return 1;    return 0;}int main(){    int i,j,a,b;    while(scanf("%d%d",&n,&p)!=EOF)    {        source=sum=0;        l=r=0;        sink=n*2+1;        NV=sink+1;        for(i=1;i<=n;i++)        {            for(j=1;j<=n;j++)            {              d[i][j]=maxn;///没有定义最大值,WA了我头疼。。。伤不起            }            d[i][i]=0;        }        for(i=1;i<=n;i++)        {            scanf("%d%d",&cow[i],&sh[i]);            sum+=cow[i];        }        for(i=1; i<=p; i++)        {            scanf("%d%d %I64d",&a,&b,&c);            r+=c;            if(d[a][b]>c)            d[b][a]=d[a][b]=c;        }        floyd();        ans=-1;        r+=2;        while(l<=r)        {            __int64 mid=(l+r)>>1LL;            if(ok(mid))            {                 r=mid-1;                 ans=mid;            }            else l=mid+1;        }        printf("%I64d\n",ans);    }    return 0;}/**/


 

原创粉丝点击