zoukankan      html  css  js  c++  java
  • 二分查找+网络流——poj 2112

    先 folyd 求出任意两点可以到达的距离,

    由于我们不知道最短距离为多少,所以用二分查找来逼近答案

    接着构建容量网络:

    增加 源点 (n+1),设置源点到牛的容量为1  (一开始以为是INF,显然是错的)

    增加 汇点 (0),设置汇点到机器的容量为 M

    在通过二分出来的那个答案,统计牛到机器的容量

    最后网络流最大流,继续二分,直到最佳答案

    View Code
    #include<stdio.h>
    #include<string.h>

    const int inf=100000000;
    const int MAXN=309;
    int map[MAXN][MAXN];
    int dis[MAXN][MAXN];
    int flow[MAXN][MAXN];
    int K,C,M;

    int min(int a,int b)
    {
    if(a<b)return a;
    else return b;
    }

    int max_flow(int n,int mat[][MAXN],int source,int sink)
    {
    int v[MAXN],c[MAXN],p[MAXN],ret=0,i,j;
    for(;;){
    for(i=0;i<n;i++)
    v[i]=c[i]=0;
    for(c[source]=inf;;){
    for(j=-1,i=0;i<n;i++)
    if(!v[i]&&c[i]&&(j==-1||c[i]>c[j]))
    j=i;
    if(j<0)return ret;
    if(j==sink)break;
    for(v[j]=1,i=0;i<n;i++)
    if(mat[j][i]>c[i]&&c[j]>c[i])
    c[i]=mat[j][i]<c[j]?mat[j][i]:c[j],p[i]=j;
    }
    for(ret+=j=c[i=sink];i!=source;i=p[i])
    mat[p[i]][i]-=j,mat[i][p[i]]+=j;
    }
    return ret;
    }

    void build(int max)
    {
    int i,j,k;
    memset(map,0,sizeof(map));

    for(i=1;i<=K;i++)
    {
    map[i][0]=M;
    }
    for(i=K+1;i<=n;i++)
    {
    map[n+1][i]=1;//一开始赋值为inf,事实上一头牛就只有一个单位容量
    }

    int n=K+C;
    for(i=K+1;i<=n;i++)
    {
    for(j=1;j<=K;j++)
    {
    if(dis[i][j]<=max)
    map[i][j]=1;
    }
    }


    }

    int main()
    {
    int n;
    while(scanf("%d%d%d",&K,&C,&M)!=EOF)
    {
    n=K+C;
    int i,j,k;

    memset(map,0,sizeof(map));
    memset(dis,0,sizeof(dis));

    int mmax=0;
    for(i=1;i<=n;i++)
    {
    for(j=1;j<=n;j++)
    {
    scanf("%d",&dis[i][j]);
    if(dis[i][j]==0)dis[i][j]=inf;
    }
    }

    for(k=1;k<=n;k++)
    {
    for(i=1;i<=n;i++)
    {
    for(j=1;j<=n;j++)
    {
    dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    }
    }
    }

    for(i=1;i<=n;i++)
    {
    for(j=1;j<=n;j++)
    {
    if(mmax<dis[i][j])
    {
    mmax=dis[i][j];
    }
    }
    }


    int l=0,r=mmax,mid;

    int min=inf;

    while(l<=r)
    {
    mid=(l+r)>>1;
    build(mid);
    int flow=max_flow(n+2,map,n+1,0);
    if(flow>=C) r=mid-1;
    else l=mid+1;

    if(flow>=C)
    {
    if(mid<min)
    min=mid;
    }
    }

    printf("%d\n",min);
    }

    return 0;
    }



  • 相关阅读:
    乐观锁+悲观锁
    python读取大文件处理方式
    ionic集成jPush极光推送
    AngularJs中$http发送post或者get请求,SpringMVC后台接收不到参数值的解决办法
    ionic开发插件之ngCordova配置安装(搬运)
    使用Ionic进行移动端APP开发
    HashMap,LinkedHashMap,TreeMap的区别
    ubuntu下node、npm、bower简易安装
    Mongodb数据更新命令(update、save)
    mongoDb地理空间索引和查询
  • 原文地址:https://www.cnblogs.com/huhuuu/p/2410745.html
Copyright © 2011-2022 走看看