Optimal Milking POJ

来源:互联网 发布:搜索引擎 数据库 区别 编辑:程序博客网 时间:2024/06/03 07:09

点击打开链接

这道题要先通过floyd求任意两点之间的最短路 再二分最长路径 抽象源点汇点 源点到牛边长是1 牛到机器根据当前最长路决定是1还是0 机器到汇点边为m

然后通过最大流判断是否可行即可

#include <stdio.h>#include <queue>#include <cstring>#include <algorithm>using namespace std;#define N 1e9struct node{    int v;    int w;    int next;};node edge[100000];int e[500][500];int first[500],dis[500],gap[500],cur[500],pre[500];int len[100000];int n1,n2,m,n,ss,ee,num1,num2,sum,ans;void addedge(int u,int v,int w){    edge[num2].v=v;    edge[num2].w=w;    edge[num2].next=first[u];    first[u]=num2++;    return;}void floyd();void binsearch();void creat(int lim);void isap();void bfs();int main(){    int i,j;    while(scanf("%d%d%d",&n1,&n2,&m)!=EOF)    {        n=n1+n2;        for(i=1;i<=n;i++)        {            for(j=1;j<=n;j++)            {                scanf("%d",&e[i][j]);                if(e[i][j]==0&&i!=j) e[i][j]=N;            }        }        floyd();        binsearch();        printf("%d\n",ans);    }    return 0;}void floyd(){    int pre[100000];    int i,j,k,t;    for(k=1;k<=n;k++)    {        for(i=1;i<=n;i++)        {            for(j=1;j<=n;j++)            {                if(e[i][j]>e[i][k]+e[k][j])                {                    e[i][j]=e[i][k]+e[k][j];                }            }        }    }    num1=0;    for(i=1;i<=n;i++)    {        for(j=i+1;j<=n;j++)        {            if(e[i][j]!=N)            {                num1++;                len[num1]=e[i][j];            }        }    }    sort(len+1,len+num1+1);    pre[0]=0;    t=num1,num1=0;    for(i=1;i<=t;i++)    {        if(len[i]!=pre[num1])        {            num1++;            pre[num1]=len[i];        }    }    memcpy(len,pre,sizeof(pre));    return;}void binsearch(){    int l,r,mid;    l=1,r=num1;    while(l<=r)    {        mid=len[(l+r)/2];        creat(mid);        isap();        if(sum>=n2)        {            r=(l+r)/2-1;            ans=mid;        }        else        {            l=(l+r)/2+1;        }    }    return;}void creat(int lim){    int i,j;    memset(first,-1,sizeof(first));    ss=n+1,ee=n+2,num2=0;    for(i=n1+1;i<=n;i++)//牛    {        for(j=1;j<=n1;j++)//机器        {            if(e[i][j]!=N&&e[i][j]!=0&&e[i][j]<=lim)            {                addedge(i,j,1);                addedge(j,i,0);            }        }    }    for(i=n1+1;i<=n;i++)    {        addedge(ss,i,1);        addedge(i,ss,0);    }    for(i=1;i<=n1;i++)    {        addedge(i,ee,m);        addedge(ee,i,0);    }    return;}void isap(){    int j,u,v,flow,minn,cnt;    bfs();    memcpy(cur,first,sizeof(first));    memset(pre,-1,sizeof(pre));    num2=n+2,sum=0,u=ss,flow=N,cnt=1;    while(dis[ss]<num2)    {        int &i=cur[u];        for(;i!=-1;i=edge[i].next)        {            v=edge[i].v;            if(dis[v]+1==dis[u]&&edge[i].w>0)            {                pre[v]=i;                u=v,flow=min(flow,edge[i].w);                if(u==ee)                {                    while(u!=ss)                    {                        j=pre[u];                        edge[j].w-=flow;                        edge[j^1].w+=flow;                        u=edge[j^1].v;                    }                    sum+=flow,flow=N;                }                break;            }        }        if(i==-1)        {            if(--gap[dis[u]]==0) break;            cur[u]=first[u];            minn=num2-1;            for(j=first[u];j!=-1;j=edge[j].next)            {                v=edge[j].v;                if(edge[j].w>0)                {                    minn=min(minn,dis[v]);                }            }            dis[u]=minn+1;            gap[dis[u]]++;            if(u!=ss)            {                u=edge[pre[u]^1].v;            }        }    }    return;}void bfs(){    queue <int> que;    int i,u,v;    memset(dis,-1,sizeof(dis));    memset(gap,0,sizeof(gap));    que.push(ee);    dis[ee]=0;    while(!que.empty())    {        u=que.front();        que.pop();        gap[dis[u]]++;        for(i=first[u];i!=-1;i=edge[i].next)        {            v=edge[i].v;            if(dis[v]==-1)            {                dis[v]=dis[u]+1;                que.push(v);            }        }    }    return;}

原创粉丝点击