标签:push sample cas 翻译 rip 最大流 minimum cte evel
Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 17933 | Accepted: 6415 | |
Case Time Limit: 1000MS |
Description
Input
Output
Sample Input
2 3 2 0 3 2 1 1 3 0 3 2 0 2 3 0 1 0 1 2 1 0 2 1 0 0 2 0
Sample Output
2
翻译:一共K台挤奶机,每台最多可以给M头牛提供服务,现在一共有C头牛,在使得C头牛全部能产奶的情况下最小化牛的最大路程。
思路:根据题设给定的直接距离的邻接矩阵,先通过floyd预处理任意两个对象之间的最短距离。之后对最大路程进行二分处理,对于每一个路程,判断最大流是否为牛的个数C.
图的建立:设源点s,汇点t,s向每头牛连一条流量为1的边,每台机器向汇点t连一条流量为M的边,若每头牛ci能在最大路程内走到机器kj,则牛向机器连一条流量为1的边。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<algorithm> #include<queue> #include<set> #include<vector> #include<cstring> #include<string> using namespace std; #define INF 0x3f3f3f3f const int K_MAX = 30+2, C_MAX = 200+2, V_MAX = K_MAX+C_MAX + 2; typedef long long ll; int V; struct edge { int to, cap, rev; edge(int to, int cap, int rev) :to(to), cap(cap), rev(rev) {} }; vector<edge>G[V_MAX]; int level[V_MAX]; int iter[V_MAX]; void add_edge(int from, int to, int cap) { G[from].push_back(edge(to, cap, G[to].size())); G[to].push_back(edge(from, 0, G[from].size() - 1)); } void bfs(int s) { memset(level, -1, sizeof(level)); queue<int>que; level[s] = 0; que.push(s); while (!que.empty()) { int v = que.front(); que.pop(); for (int i = 0; i < G[v].size(); i++) { edge&e = G[v][i]; if (e.cap > 0 && level[e.to] < 0) { level[e.to] = level[v] + 1; que.push(e.to); } } } } int dfs(int v, int t, int f) { if (v == t)return f; for (int &i = iter[v]; i < G[v].size(); i++) { edge&e = G[v][i]; if (e.cap > 0 && level[v] < level[e.to]) { int d = dfs(e.to, t, min(f, e.cap)); if (d > 0) { e.cap -= d; G[e.to][e.rev].cap += d; return d; } } } return 0; } int max_flow(int s, int t) { int flow = 0; for (;;) { bfs(s); if (level[t] < 0)return flow; memset(iter, 0, sizeof(iter)); int f; while ((f = dfs(s, t, INT_MAX))>0) { flow += f; } } } int k, c, m,s,t; int d[K_MAX+C_MAX][K_MAX+C_MAX]; void floyd() { for (int K = 0; K < k + c; K++) for (int i = 0; i < k + c; i++) for (int j = 0; j < k + c; j++) d[i][j] = min(d[i][j],d[i][K]+d[K][j]); } bool C(int limit) { for (int i = 0; i < V;i++) { G[i].clear(); } for (int i = 0; i < c;i++) { add_edge(s,i,1); } for (int i = 0; i < k;i++) { add_edge(c+i,t,m); } for (int i = 0; i < c;i++) {//牛与机器连边,i:牛 for (int j = 0; j < k;j++) {//j:机器 if (d[j][k+i] <= limit) add_edge(i, c + j, 1); } } return max_flow(s,t)==c;//如果最大流等于牛的个数 } int main() { while (scanf("%d%d%d", &k, &c, &m) != EOF) { for (int i = 0; i < k + c; i++) for (int j = 0; j < k + c; j++) { scanf("%d", &d[i][j]); if (!d[i][j])d[i][j] = INF;//!!Entities not directly connected by a path have a distance of 0 } floyd(); //0~c-1:牛 //c~c+k-1:挤奶机 s = k + c, t = s+1,V=t+1; int lb = 0, ub = 200 * (k + c); while (ub - lb > 1) { int mid = (lb+ub) >> 1; if (C(mid))ub = mid; else lb = mid; } printf("%d\n",ub); } return 0; }
标签:push sample cas 翻译 rip 最大流 minimum cte evel
原文地址:http://www.cnblogs.com/ZefengYao/p/7216909.html