题目大意:n块草地,每块草地有一些牛,每块草地有雨棚,可以容纳一定量的牛。草地间有路,可以无限通过牛,牛通过某条路有一定的时间。现在求最短的时间让所有的牛都能到雨棚。
题目分析:最大流。题目给的是无向图,所以先跑一遍floyd,求出任意2块草地之间最少的时间。因为牛通过路的时间是累加的,所以要把无向图改成有向图,保证牛走某条路后时间是累加的。方法是拆点,将草地i拆成i和i+n,2个点,源点到每个i建边,边权为草地i初始的牛的数量。每个i+n到汇点建边,边权为第i个草地能容纳的牛的数量。如果i到j有路,那么i和j+n连边,这样保证牛经过i到j的最短路后,不能返回,只能到达汇点,从而实现对牛的路径的控制。要求最短的时间,那么二分时间,每次求一次最大流,流量等于牛的总数才合法。
本题数据范围比较大,要__int64。
详情请见代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 405;
const int M = 160005;
typedef __int64 ll;
const ll inf = ((ll)1<<38);
ll dist[N][N];
int head[N],dis[N],sta[N],que[N],cnt[N],rpath[N];
int cow[205],stay[205];
struct node
{
int to,c,next,pre;
}arc[M];
int n,m,num,sum;
void build(int s,int e,int cap)
{
arc[num].to = e;
arc[num].c = ca