zoukankan      html  css  js  c++  java
  • POJ2391_Ombrophobic Bovines

    有F个地方,每个地方有一定数量的牛,能够容纳一定数量的牛,某些地方之间有边,表示走两点之间需要消耗的时间。

    现在求使得所有的牛都被容纳所需要的最少的时间。

    由于时间是一个不确定的因素,我们需要二分。

    假设当前二分的时间为t,那么从某一点出发距离不要超过t的点都是可以连边的,于是最后只需要跑最大流验证是否满流即可。

    此题给的数据居然爆int,真是深坑啊。

    召唤代码君:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #define maxn 1122
    #define maxm 555555
    typedef long long ll;
    using namespace std;
    
    ll inf=~0U>>2;
    ll to[maxm],next[maxm],c[maxm],first[maxn],edge;
    ll cow[maxn],hold[maxn],d[maxn],tag[maxn],TAG=520;
    ll Q[maxm],bot,top;
    ll dis[maxn][maxn],f[maxn],g[maxn][maxn];
    bool can[maxn];
    ll n,m,sumcow,ans,s,t;
    
    void _init()
    {
        sumcow=0;
        for (int i=1; i<=n; i++)
            for (int j=1; j<=n; j++) dis[i][j]=-1;
    }
    
    void spfa(ll x)
    {
        for (int i=1; i<=n; i++) f[i]=inf;
        Q[bot=top=1]=x,f[x]=0;
        while (bot<=top)
        {
            ll cur=Q[bot++];
            for (int i=1; i<=n; i++)
                if (dis[cur][i]!=-1 && f[cur]+dis[cur][i]<f[i])
                {
                    Q[++top]=i;
                    f[i]=f[cur]+dis[cur][i];
                }
        }
        for (int i=1; i<=n; i++) g[x][i]=f[i];
    }
    
    void _input()
    {
        ll U,V,W;
        for (int i=1; i<=n; i++) scanf("%I64d%I64d",&cow[i],&hold[i]),sumcow+=cow[i];
        while (m--)
        {
            scanf("%I64d%I64d%I64d",&U,&V,&W);
            if (dis[U][V]==-1) dis[U][V]=dis[V][U]=W;
                else if (W<dis[U][V]) dis[U][V]=dis[V][U]=W;
        }
        for (int i=1; i<=n; i++) if (cow[i]>0) spfa(i);
    }
    
    void addedge(ll U,ll V,ll W)
    {
        edge++;
        to[edge]=V,c[edge]=W,next[edge]=first[U],first[U]=edge;
        edge++;
        to[edge]=U,c[edge]=0,next[edge]=first[V],first[V]=edge;
    }
    
    bool bfs()
    {
        Q[bot=top=1]=t,d[t]=0,tag[t]=++TAG;
        while (bot<=top)
        {
            ll cur=Q[bot++];
            for (int i=first[cur]; i!=-1; i=next[i])
            {
                if (c[i^1]>0 && tag[to[i]]!=TAG)
                {
                    tag[to[i]]=TAG,Q[++top]=to[i];
                    d[to[i]]=d[cur]+1,can[to[i]]=false;
                    if (to[i]==s) return true;
                }
            }
        }
        return false;
    }
    
    ll dfs(ll cur,ll num)
    {
        if (cur==t) return num;
        ll tmp=num,k;
        for (int i=first[cur]; i!=-1; i=next[i])
            if (c[i]>0 && d[to[i]]==d[cur]-1 && tag[to[i]]==TAG && !can[to[i]])
            {
                k=dfs(to[i],min(c[i],num));
                if (k) num-=k,c[i]-=k,c[i^1]+=k;
                if (num==0) break;
            }
        if (num) can[cur]=true;
        return tmp-num;
    }
    
    bool check(ll x)
    {
        s=0,t=2*n+1,edge=-1,ans=0;
        for (int i=s; i<=t; i++) first[i]=-1;
        for (int i=1; i<=n; i++)
        {
            if (cow[i]>0)
            {
                addedge(s,i,cow[i]);
                for (int j=1; j<=n; j++)
                    if (g[i][j]<=x) addedge(i,j+n,cow[i]);
            }
            addedge(i+n,t,hold[i]);
        }
        while (bfs()) ans+=dfs(s,inf);
        return ans==sumcow;
    }
    
    int main()
    {
        inf*=inf;
        while (scanf("%I64d%I64d",&n,&m)!=EOF)
        {
            _init();
            _input();
            if (!check(inf-1))
            {
                puts("-1");
                continue;
            }
            ll l=0,r=inf-2,mid;
            while (l<r)
            {
                mid=l/2+r/2;
                if (l&r&1) mid++;
                if (check(mid)) r=mid;
                    else l=mid+1;
            }
            printf("%I64d
    ",l);
        }
        return 0;
    }
    如有转载,请注明出处(http://www.cnblogs.com/lochan)
  • 相关阅读:
    给一个二维数组随机赋值
    sql server use WAITFOR DELAY to wait some milliseconds
    sql server print time with milliseconds
    UE4 LeapMotion 获取手掌朝向
    Unity打包Android出现Failed to find Build Tools revision
    UE4中Yaw,Roll,Pitch分别对应什么轴?
    Unity 遍历场景所有物体(包括隐藏及被禁用的物体)
    C#-Linq扩展方法DistinctBy
    Unity编辑器扩展--Scene Manager
    Unity查找功能编辑器扩展Searcher
  • 原文地址:https://www.cnblogs.com/lochan/p/3854845.html
Copyright © 2011-2022 走看看