BZOJ 1738: [Usaco2005 mar]Ombrophobic Bovines 发抖的牛

Description

约翰的牛们非常害怕淋雨,那会使他们瑟瑟发抖.他们打算安装一个下雨报警器,并且安排了一个撤退计划.他们需要计算最少的让所有牛进入雨棚的时间.    牛们在农场的F(1≤F≤200)个田地上吃草.有P(1≤P≤1500)条双向路连接着这些田地.路很宽,无限量的牛可以通过.田地上有雨棚,雨棚有一定的容量,牛们可以瞬间从这块田地进入这块田地上的雨棚    请计算最少的时间,让每只牛都进入雨棚.

Input

第1行:两个整数F和P;

第2到F+1行:第i+l行有两个整数描述第i个田地,第一个表示田地上的牛数,第二个表示田地上的雨棚容量.两个整数都在0和1000之间.

第F+2到F+P+I行:每行三个整数描述一条路,分别是起点终点,及通过这条路所需的时间(在1和10^9之间).

Output

一个整数,表示最少的时间.如果无法使牛们全部进入雨棚,输出-1.

题解:

首先floyd处理出点到点之间的最短时间,然后二分一个时间,网络流判断是否全部进入雨棚。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include<queue>
//  by zrt
//  problem:
//  无论你在什么时候开始,重要的是开始以后就不要停止。
using namespace std ;
typedef long long LL ;
const double eps(1e-10) ;
const int inf(0x3f3f3f3f) ;
int f,p;
LL INF=0x3f3f3f3f3f3f3f3f;
int ni[205],fi[205];
LL map[205][205];
int S,T;
int H[404],X[340000],P[340000],tot;
int  flow[340000];
int d[406];
queue<int> q;
bool bfs(){
    memset(d,0,sizeof d);
    d[S]=1;q.push(S);
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=H[x];i;i=X[i]){
            if(flow[i]>0&&!d[P[i]]){
                d[P[i]]=d[x]+1;
                q.push(P[i]);
            }
        }
    }
    return d[T];
}
int dfs(int x,int a){
    int f=a,tmp;
    if(x==T||a==0) return a;
    for(int i=H[x];i;i=X[i]){
        if(flow[i]>0&&d[P[i]]==d[x]+1){
            tmp=dfs(P[i],min(a,flow[i]));
            a-=tmp;
            flow[i]-=tmp;
            flow[i^1]+=tmp;
            if(!a) break;
        }
    }
    if(f==a) d[x]=-1;
//  printf("%d\n",f-a);
    return f-a;
}
int Dinic(){
    int f=0;
    while(bfs()) f+=dfs(S,inf);
    return f;
}
inline void add(int x,int y,int z){
    P[++tot]=y;X[tot]=H[x];H[x]=tot;flow[tot]=z;
}
int sum=0;
bool judge(LL lim){
    tot=1;memset(H,0,sizeof H);
    for(int i=1;i<=f;i++){
        add(S,i<<1,ni[i]);
        add(i<<1,S,0);
        add(i<<1,i<<1|1,inf);
        add(i<<1|1,i<<1,0);
        add(i<<1|1,T,fi[i]);
        add(T,i<<1|1,0);
    }
    for(int i=1;i<=f;i++){
        for(int j=1;j<=f;j++){
            if(i!=j) {
                if(map[i][j]<=lim){
                    add(i<<1,j<<1|1,inf);
                    add(j<<1|1,i<<1,0);
                }
            }
        }
    }
    if(Dinic()==sum) return true;
    else return false;
}
int main(){
    #ifdef LOCAL
    freopen("in.txt","r",stdin) ;
    freopen("out.txt","w",stdout) ;
    #endif
    scanf("%d%d",&f,&p);
    S=0,T=1;

    for(int i=1;i<=f;i++) scanf("%d%d",&ni[i],&fi[i]),sum+=ni[i];
    memset(map,0x3f,sizeof map);
    for(int i=0,x,y,z;i<p;i++){
        scanf("%d%d%d",&x,&y,&z);
        map[x][y]=map[y][x]=min(map[x][y],(LL)z);
    //  map[x][y]=z;
    }
    for(int k=1;k<=f;k++){
        for(int i=1;i<=f;i++){
            if(i==k) continue;
            for(int j=1;j<=f;j++){
                if(i==j||k==j) continue;
                 map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
            }
        }
    }
    if(!judge(INF-1)) {
        puts("-1");
        return 0;
    }
    LL l=-1,r=INF-1,m;
    while(r-l>1){
        m=(l+r)/2;
        if(judge(m)){
            r=m;
        }else l=m;
    }
    printf("%lld\n",r);
    return 0 ;
}
时间: 2024-10-10 21:41:59

BZOJ 1738: [Usaco2005 mar]Ombrophobic Bovines 发抖的牛的相关文章

BZOJ 1738: [Usaco2005 mar]Ombrophobic Bovines 发抖的牛( floyd + 二分答案 + 最大流 )

一道水题WA了这么多次真是.... 统考终于完 ( 挂 ) 了...可以好好写题了... 先floyd跑出各个点的最短路 , 然后二分答案 m , 再建图. 每个 farm 拆成一个 cow 点和一个 shelter 点, 然后对于每个 farm x : S -> cow( x ) = cow( x ) 数量 , shelter( x ) -> T = shelter( x ) 容量 ; 对于每个dist( u , v ) <= m 的 cow( u ) -> shelter( v

BZOJ1738 [Usaco2005 mar]Ombrophobic Bovines 发抖的牛

先预处理出来每个点对之间的最短距离 然后二分答案,网络流判断是否可行就好了恩 1 /************************************************************** 2 Problem: 1738 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:404 ms 7 Memory:9788 kb 8 **********************************************

【BZOJ1738】【POJ2391】【Usaco2005 mar】 Ombrophobic Bovines 发抖的牛 网络流

题意: 约翰的牛们非常害怕淋雨,那会使他们瑟瑟发抖.他们打算安装一个下雨报警器,并且安排了一个撤退计划.他们需要计算最少的让所有牛进入雨棚的时间.    牛们在农场的F(1≤F≤200)个田地上吃草.有P(1≤P≤1500)条双向路连接着这些田地.路很宽,无限量的牛可以通过.田地上有雨棚,雨棚有一定的容量,牛们可以瞬间从这块田地进入这块田地上的雨棚    请计算最少的时间,让每只牛都进入雨棚. input 第1行:两个整数F和P; 第2到F+1行:第i+l行有两个整数描述第i个田地,第一个表示田

BZOJ 1739: [Usaco2005 mar]Space Elevator 太空电梯

题目 1739: [Usaco2005 mar]Space Elevator 太空电梯 Time Limit: 5 Sec  Memory Limit: 64 MB Description The cows are going to space! They plan to achieve orbit by building a sort of space elevator: a giant tower of blocks. They have K (1 <= K <= 400) differe

BZOJ 1734: [Usaco2005 feb]Aggressive cows 愤怒的牛( 二分答案 )

最小最大...又是经典的二分答案做法.. -------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define rep( i , n ) for( int i = 0 ; i < n ; ++i ) #defin

bzoj 1734: [Usaco2005 feb]Aggressive cows 愤怒的牛

1734: [Usaco2005 feb]Aggressive cows 愤怒的牛 Description Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. The stalls are located along a straight line at positions x1,...,xN (0 <= xi <= 1,000,000,000). His C (2 <= C &l

bzoj:1681: [Usaco2005 Mar]Checking an Alibi 不在场的证明

Description A crime has been comitted: a load of grain has been taken from the barn by one of FJ's cows. FJ is trying to determine which of his C (1 <= C <= 100) cows is the culprit. Fortunately, a passing satellite took an image of his farm M (1 &l

BZOJ 1682: [Usaco2005 Mar]Out of Hay 干草危机

Description 牛们干草要用完了!贝茜打算去勘查灾情. 有N(2≤N≤2000)个农场,M(≤M≤10000)条双向道路连接着它们,长度不超过10^9.每一个农场均与农场1连通.贝茜要走遍每一个农场.她每走一单位长的路,就要消耗一单位的水.从一个农场走到另一个农场,她就要带上数量上等于路长的水.请帮她确定最小的水箱容量.也就是说,确定某一种方案,使走遍所有农场通过的最长道路的长度最小,必要时她可以走回头路. Input 第1行输入两个整数N和M;接下来M行,每行输入三个整数,表示一条道路

bzoj 1680\1740 : [Usaco2005 Mar]Yogurt factory 贪心 双倍经验

1680: [Usaco2005 Mar]Yogurt factory Description The cows have purchased a yogurt factory that makes world-famous Yucky Yogurt. Over the next N (1 <= N <= 10,000) weeks, the price of milk and labor will fluctuate weekly such that it will cost the com