luogu2402 奶牛隐藏
2017-12-27 20:27
211 查看
题目描述
在一个农场里有n块田地。某天下午,有一群牛在田地里吃草,他们分散在农场的诸多田地上,农场由m条无向的路连接,每条路有不同的长度。突然,天降大雨,奶牛们非常混乱,想要快点去躲雨。已知每个田地都建立有一个牛棚,但是每个牛棚只能容纳一定数量的牛躲雨,如果超过这个数量,那多出的牛只能去别的田地躲雨。奶牛们每移动1的距离花费1时间,奶牛们想知道它们全部都躲进牛棚,最少需要多少时间。(即最后一头奶牛最少要花多久才能躲进牛棚)。
输入输出格式
输入格式:
第一行输入两个整数N,M。N表示田地块数,M表示路径数。接下来N行,每行两个整数S,P,分别表示该田地现在有几头牛以及该田地的牛棚最多可以容纳多少牛。
接下来M行,每行3个整数A,B,C,表示存在一条路径连接A,B,并且它的长度为C。
输出格式:
一个整数表示所有奶牛全都躲进牛棚所用的最少时间。如果无法使全部奶牛都躲进牛棚,输出-1。输入输出样例
输入样例#1:
3 4 7 2 0 4 2 6 1 2 40 3 2 70 2 3 90 1 3 120
输出样例#1:
110
说明
【样例解释】
1号点的两只牛直接躲进1号牛棚,剩下的5只中,4只跑去2号点,还有一只从1->2->3,3号点的2只牛也直接躲进去,这样最慢的牛花费的时间是110。数据范围 : 对于100%的数据,N<=200 M<=1500
网络流,首先floyed跑出每两个农场间的最短路考虑二分答案,每次只把路径长度小与二分的答案的边构图
网络流判断是否满流即可,注意开long long
# include <bits/stdc++.h> # define IL inline # define RG register # define Fill(a, b) memset(a, b, sizeof(a)) # define Copy(a, b) memcpy(a, b, sizeof(a)) using namespace std; typedef long long ll; const int _(410), __(4e5 + 10); const ll INF(1e18); IL ll Read(){ RG char c = getchar(); RG ll x = 0, z = 1; for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1; for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48); return x * z; } # define int ll int n, m, num, w[__], fst[_], nxt[__], to[__], cnt, s[_], p[_]; int S, T, lev[_], cur[_], max_flow, ans, dis[_][_]; queue <int> Q; IL void Add(RG int u, RG int v, RG int f){ if(!f) return; w[cnt] = f; to[cnt] = v; nxt[cnt] = fst[u]; fst[u] = cnt++; w[cnt] = 0; to[cnt] = u; nxt[cnt] = fst[v]; fst[v] = cnt++; } IL int Dfs(RG int u, RG int maxf){ if(u == T) return maxf; RG int ret = 0; for(RG int &e = cur[u]; e != -1; e = nxt[e]){ if(lev[to[e]] != lev[u] + 1 || !w[e]) continue; RG int f = Dfs(to[e], min(w[e], maxf - ret)); ret += f; w[e ^ 1] += f; w[e] -= f; if(ret == maxf) break; } return ret; } IL bool Bfs(){ Fill(lev, 0); lev[S] = 1; Q.push(S); while(!Q.empty()){ RG int u = Q.front(); Q.pop(); for(RG int e = fst[u]; e != -1; e = nxt[e]){ if(lev[to[e]] || !w[e]) continue; lev[to[e]] = lev[u] + 1; Q.push(to[e]); } } return lev[T]; } IL bool Check(RG int lim){ Fill(fst, -1); cnt = 0; for(RG int i = 1; i <= n; i++) Add(S, i, s[i]), Add(i + n, T, p[i]); for(RG int i = 1; i <= n; i++) for(RG int j = 1; j <= n; j++) if(dis[i][j] <= lim) Add(i, j + n, INF); for(max_flow = 0; Bfs(); ) Copy(cur, fst), max_flow += Dfs(S, INF); return max_flow == num; } # undef int int main(RG int argc, RG char* argv[]){ # define int ll n = Read(); m = Read(); Fill(dis, 63); T = n + n + 1; for(RG int i = 1; i <= n; i++) dis[i][i] = 0, s[i] = Read(), p[i] = Read(), num += s[i]; for(RG int i = 1, a, b, c; i <= m; i++){ a = Read(); b = Read(); c = Read(); if(c >= dis[a][b]) continue; dis[a][b] = dis[b][a] = c; } for(RG int k = 1; k <= n; k++) for(RG int i = 1; i <= n; i++) for(RG int j = 1; j <= n; j++) dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]); RG int l = 0, r = INF, ans = -1; while(l <= r){ RG int mid = (l + r) >> 1; if(Check(mid)) ans = mid, r = mid - 1; else l = mid + 1; } printf("%lld\n", ans); return 0; }
相关文章推荐
- luogu2402奶牛隐藏
- luogu(P1868 饥饿的奶牛)
- 【Luogu1345】奶牛的电信(网络流)
- Floyd+最大流——Luogu2402 奶牛隐藏
- [Luogu1843]奶牛晒衣服
- [luogu1843] 奶牛晒衣服
- luogu 2848 奶牛确认单
- [luogu2742]:[USACO5.1]圈奶牛Fencing the Cows
- Luogu 1842 奶牛玩杂技
- luogu P1345 [USACO5.4]奶牛的电信Telecowmunication
- 【luogu2840】 Moocast(gold)奶牛广播-金
- luogu1472 奶牛家谱 Cow Pedigrees
- elfinder中通过DirectoryStream.Filter实现筛选隐藏目录(二)
- 删除隐藏的本地连接
- 隐藏软件键盘的方法
- 间谍新高度:间谍组织Turla利用卫星通信隐藏C&C服务器
- easyui datebox只显示年月选择,隐藏日期
- CRM热潮中的冷思考:风光的背后隐藏什么?
- android 控件的隐藏属性 .
- luogu 1043 数字游戏(区间dp)