zoukankan      html  css  js  c++  java
  • Ombrophobic Bovines (二分 + 弗罗伊得+最大流 )

    FJ's cows really hate getting wet so much that the mere thought of getting caught in the rain makes them shake in their hooves. They have decided to put a rain siren on the farm to let them know when rain is approaching. They intend to create a rain evacuation plan so that all the cows can get to shelter before the rain begins. Weather forecasting is not always correct, though. In order to minimize false alarms, they want to sound the siren as late as possible while still giving enough time for all the cows to get to some shelter. 

    The farm has F (1 <= F <= 200) fields on which the cows graze. A set of P (1 <= P <= 1500) paths connects them. The paths are wide, so that any number of cows can traverse a path in either direction. 

    Some of the farm's fields have rain shelters under which the cows can shield themselves. These shelters are of limited size, so a single shelter might not be able to hold all the cows. Fields are small compared to the paths and require no time for cows to traverse. 

    Compute the minimum amount of time before rain starts that the siren must be sounded so that every cow can get to some shelter.

    Input

    * Line 1: Two space-separated integers: F and P 

    * Lines 2..F+1: Two space-separated integers that describe a field. The first integer (range: 0..1000) is the number of cows in that field. The second integer (range: 0..1000) is the number of cows the shelter in that field can hold. Line i+1 describes field i. 

    * Lines F+2..F+P+1: Three space-separated integers that describe a path. The first and second integers (both range 1..F) tell the fields connected by the path. The third integer (range: 1..1,000,000,000) is how long any cow takes to traverse it.

    Output

    * Line 1: The minimum amount of time required for all cows to get under a shelter, presuming they plan their routes optimally. If it not possible for the all the cows to get under a shelter, output "-1".

    Sample Input

    3 4
    7 2
    0 4
    2 6
    1 2 40
    3 2 70
    2 3 90
    1 3 120

    Sample Output

    110

    Hint

    OUTPUT DETAILS: 

    In 110 time units, two cows from field 1 can get under the shelter in that field, four cows from field 1 can get under the shelter in field 2, and one cow can get to field 3 and join the cows from that field under the shelter in field 3. Although there are other plans that will get all the cows under a shelter, none will do it in fewer than 110 time units.

    被这道题卡时间卡到自闭

    tle无数次,写了好几天

    事实证明本题并没有卡邻接矩阵

    我没想到是因为我二分的界限tle的

    平常写的二分都是直接从最大·界限开始缩小

    可是本题并不行如果跑循找出二分的最大界限就可以通过了

    其实二分是一个log

    就是t在了这上面吧

    本体不难理解就是先把跑一边floyd将每两个带你之间的距离固定

    二分最大距离吧小于答案的建边 如果能跑到满流就符合

    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    using namespace std;
    
    long long dis[205][205];
    int num=0;
    const int INF = 0x7fffffff;
    int IN[205];
    int OUT[205];
    int F,P;
    int flag;
    
    int level[405];
    int cnt;
    struct Dinic
    {
        int c;
        int f;
    } edge[405][405];
    bool dinic_bfs()      //bfs方法构造层次网络
    {
        queue<int> q;
        memset(level, 0, sizeof(level));
        q.push(0);
        level[0] = 1;
        int u, v;
        while (!q.empty())
        {
            u = q.front();
            q.pop();
            for (v = 1; v <= cnt; v++)
            {
                if (!level[v] && edge[u][v].c>edge[u][v].f)
                {
                    level[v] = level[u] + 1;
                    q.push(v);
                }
            }
        }
        return level[cnt] != 0;                //question: so it must let the sink node is the Mth?/the way of yj is give the sink node's id
    }
    int dinic_dfs(int u, int cp)             //use dfs to augment the flow
    {
        int tmp = cp;
        int v, t;
        if (u == cnt)
            return cp;
        for (v = 1; v <= cnt&&tmp; v++)
        {
            if (level[u] + 1 == level[v])
            {
                if (edge[u][v].c>edge[u][v].f)
                {
                    t = dinic_dfs(v, min(tmp, edge[u][v].c - edge[u][v].f));
                    edge[u][v].f += t;
                    edge[v][u].f -= t;
                    tmp -= t;
                }
            }
        }
        return cp - tmp;
    }
    int dinic()
    {
        int sum=0, tf=0;
        while (dinic_bfs())
        {
            while (tf = dinic_dfs(0, INF))
                sum += tf;
        }
        return sum;
    }
    
    
    int check(long long x)
    {
        //建图 调用dinic
        memset(edge,0,sizeof(edge));
        for(int i=1; i<=F; i++) //拆点
        {
            edge[0][i].c=OUT[i];
        }
        for(int i=1; i<=F; i++) //P+i对应点
        {
            edge[F+i][cnt].c=IN[i];
        }
        for(int i=1; i<=F; i++)
        {
            for(int j=1; j<=F; j++)
            {
                if(dis[i][j]<=x)
                {
                    edge[i][F+j].c=1e9;
                }
            }
        }
        if(dinic()==num) {flag=1;return 1;}
        return 0;
    }
    
    
    int main()
    {
        scanf("%d%d",&F,&P);
        {
            flag=0;
            num=0;
            cnt=2*F+1;
            for(int i=1; i<=F; i++)
            {
                scanf("%d%d",&OUT[i],&IN[i]);
                num+=OUT[i];
            }
            for(int i=1;i<=F;i++)
            {
                for(int j=1;j<=F;j++)
                {
                    dis[i][j]=1e18;
                }
            }
            for(int i=1; i<=P; i++)
            {
                int tmp1,tmp2;
                long long tmp3;
                scanf("%d%d%lld",&tmp1,&tmp2,&tmp3);
                if(tmp3<dis[tmp1][tmp2])
                {
                    dis[tmp1][tmp2]=tmp3;
                    dis[tmp2][tmp1]=tmp3;
                }
            }
            for(int i=1;i<=F;i++)
            {
                dis[i][i]=0;
            }
            for(int i=1; i<=F; i++)
            {
                for(int j=1; j<=F; j++)
                {
                    for(int k=1; k<=F; k++)
                    {
                        dis[j][k]=min(dis[j][i]+dis[i][k],dis[j][k]);
                    }
                }
            }
            long long l=0,r=0;
            for(int i=1;i<=F;i++)
            {
                for(int j=1;j<=F;j++)
                {
                    if(dis[i][j]<1e17)
                    {
                        r=max(r,dis[i][j]+1);
                    }
                }
            }
            long long mid;
            while(l<=r)
            {
                mid=(l+r)/2;
                if(check(mid)) r=mid-1;
                else l=mid+1;
            }
            if(flag==0)
            {
                printf("-1
    ");
            }
            else
            {
                printf("%lld
    ",l);
            }
        }
    }
    
  • 相关阅读:
    mysql导入数据到oracle中
    CAS代理配置
    CAS登录时不仅仅需要用户名来确认身份的情况
    easyui datalist按组多选
    easyui tree loadFilter的使用
    sketchup
    Spring Autowired 注入失败总是Null
    table sorting–angularjs
    mac系统下mysql开机启动总是3307
    angularjs 实现 文件拖拽,缩略图显示
  • 原文地址:https://www.cnblogs.com/caowenbo/p/11852225.html
Copyright © 2011-2022 走看看