zoukankan      html  css  js  c++  java
  • POJ 2112 Optimal Milking 【网络流】【二分】【最短路】

    题意:

    k c m 分别代表挤奶机数量,牛数量,和挤奶机容量。

    接下来(n=k+c)n*n的矩阵A,代表挤奶机或者牛的距离,如果对角线都为0,如果非对角线没有直接路相连也为0。

    1 <= K <= 30  1 <= C <= 200  1 <= M <= 15  0<=Aij<=200

    求:在机器不能过载工作的前提下,最远的牛到挤奶机的距离的最小值。

    思路:

    1.先跑一遍FLOYD求出任何两点的最短路。

    2.二分最远的距离,从源点到1到k号点的边容量为m,然后将权重不超过最远距离的边加进图中容量为1,最后将每头牛与汇点连容量为1的边。

    3.如果最大流跑出来是牛的数量那么符合条件,注意这种情况是找YES_LEFT的情况。

    坑点:

    1.第二次被输入数据带有k的题目搞傻逼了,这种经常被用到的循环变量下次一定小心。

    2.边权不超过200我tm就直接在1到200之间枚举了...无脑值无限大

    致谢:

    感谢卿学姐邻接表版的当前弧优化的dinic模板。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<string.h>
    #define MAXN 500
    #define MAXM 50000
    using namespace std;
    const int inf=0x3f3f3f3f;
    struct Edge
    {
        int v,c,f,nx;
        Edge() {}
        Edge(int v,int c,int f,int nx):v(v),c(c),f(f),nx(nx) {}
    } E[MAXM];
    int G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],sz;
    void init()
    {
        sz=0; memset(G,-1,sizeof(G));
    }
    void add_edge(int u,int v,int c)
    {
        E[sz]=Edge(v,c,0,G[u]); G[u]=sz++;
        E[sz]=Edge(u,0,0,G[v]); G[v]=sz++;
    }
    bool bfs(int S,int T)
    {
        static int Q[MAXN]; memset(dis,-1,sizeof(dis));
        dis[S]=0; Q[0]=S;
        for (int h=0,t=1,u,v,it;h<t;++h)
        {
            for (u=Q[h],it=G[u];~it;it=E[it].nx)
            {
                if (dis[v=E[it].v]==-1&&E[it].c>E[it].f)
                {
                    dis[v]=dis[u]+1; Q[t++]=v;
                }
            }
        }
        return dis[T]!=-1;
    }
    int dfs(int u,int T,int low)
    {
        if (u==T) return low;
        int ret=0,tmp,v;
        for (int &it=cur[u];~it&&ret<low;it=E[it].nx)
        {
            if (dis[v=E[it].v]==dis[u]+1&&E[it].c>E[it].f)
            {
                if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f)))
                {
                    ret+=tmp; E[it].f+=tmp; E[it^1].f-=tmp;
                }
            }
        }
        if (!ret) dis[u]=-1; return ret;
    }
    int dinic(int S,int T)
    {
        int maxflow=0,tmp;
        while (bfs(S,T))
        {
            memcpy(cur,G,sizeof(G));
            while (tmp=dfs(S,T,inf)) maxflow+=tmp;
        }
        return maxflow;
    }
    struct e{
        int st,ed,dis;
        e(){}
        e(int a,int b,int c){
            st=a;ed=b;dis=c;
        }
    };
    bool cmp(e a,e b){
        return a.dis<b.dis;
    }
    e eee[100050];
    
    int pho[300][300];
    int main()
    {
        int k,c,m;
        scanf("%d%d%d",&k,&c,&m);
        for(int i=1;i<=k+c;i++){
            for(int j=1;j<=k+c;j++){
                scanf("%d",&pho[i][j]);
                if(pho[i][j]==0&&i!=j){
                    pho[i][j]=inf;
                }
            }
        }
        for(int kk=1;kk<=k+c;kk++){
            for(int i=1;i<=k+c;i++){
                for(int j=1;j<=k+c;j++){
                    if(pho[i][j]>pho[i][kk]+pho[kk][j]){
                        pho[i][j]=pho[i][kk]+pho[kk][j];
                    }
                }
            }
        }
        int num=0;
        for(int i=1;i<=k+c;i++){
            for(int j=1;j<=k+c;j++){
                eee[num++]=e(i,j,pho[i][j]);
            }
        }
        sort(eee,eee+num,cmp);
        int tnum=0;
        int s=0,t=k+c+1;
        int ans=0;
        int l=1,r=50000;
        while(l<=r){
            int mid=(l+r)>>1;
            init();
            for(int j=1;j<=k;j++){
                add_edge(0,j,m);
            }
            for(int j=k+1;j<=k+c;j++){
                add_edge(j,t,1);
            }
            tnum=0;
            while(tnum<num&&eee[tnum].dis<=mid){
                if(eee[tnum].st>k&&eee[tnum].ed<=k){
                    add_edge(eee[tnum].ed,eee[tnum].st,1);
                }
                tnum++;
            }
            if(dinic(s,t)>=c)r=mid-1;
            else l=mid+1;
        }
        printf("%d
    ",l);
    }
  • 相关阅读:
    TabActivity 、fragemnt+fragment 和 Fragment+Viewpager 优缺点
    Android App的签名打包(晋级篇)
    Android ProgressBar 进度条荧光效果
    Android UI【android 仿微信、QQ聊天,带表情,可翻页,带翻页拖动缓冲】
    Android UI--自定义ListView(实现下拉刷新+加载更多)
    Android平台下利用zxing实现二维码开发
    自定义组件---图片和文字实现ImageButton效果
    JNI由浅入深_10_JNI 综合开发
    开关按钮实现
    Android Asynctask与Handler的比较,优缺点区别,Asynctask源码
  • 原文地址:https://www.cnblogs.com/tun117/p/5379588.html
Copyright © 2011-2022 走看看