标签:
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1774
input | output |
---|---|
3 2 1 3 1 3 1 3 |
Yes 1 2 1 3 2 3 |
2 1 1 3 1 3 |
No
|
有很多人要剃胡子,有个很神奇的理发师,可以在每分钟给k个人护理。每个人必须被护理两次。给你每个人进入理发店的时间和耐心,输出在什么时候给这些人剪胡子。
发现时间只有1000,那么可以每一分钟建立一个节点,然后连到人的节点上,容量为1,表示每个人1分钟最多被护理一次;每个人连接一条边到T,容量为2,表示每个人需要被护理两次;从S连接容量为k的边到每个时间,表示每一分钟可以处理k个人。然后跑一发Dinic,最后在残余网络上找解就好。详见代码:
#include<iostream> #include<stack> #include<vector> #include<cstring> #include<algorithm> #include<queue> #define MAX_V 4567 #define MAX_N 10004 #define INF 2500005 using namespace std; struct edge{int to,cap,rev;bool isRev;}; vector<edge> G[MAX_N]; int level[MAX_V]; int iter[MAX_V]; void add_edge(int from,int to,int cap) { G[from].push_back((edge) {to, cap, G[to].size(),0}); G[to].push_back((edge) {from, 0, G[from].size() - 1,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, INF)) > 0) { flow += f; } } } int n,k; int t[MAX_N],r[MAX_N]; int m=2222; int S=3232; int T=3332; int ans[MAX_N][2]; int main() { scanf("%d%d", &n, &k); memset(ans, -1, sizeof(ans)); for (int i = 0; i < n; i++) { scanf("%d%d", &t[i], &r[i]); for (int j = 0; j < r[i]; j++) add_edge(j + t[i], i + m, 1); } for (int i = 0; i < m; i++)add_edge(S, i, k); for (int i = 0; i < n; i++)add_edge(i + m, T, 2); int f = max_flow(S, T); if (f != 2 * n) { cout << "No" << endl; return 0; } printf("Yes\n"); for (int i = 0; i < m; i++) { for (int j = 0; j < G[i].size(); j++) { if(G[i][j].isRev||(G[i][j].cap==1))continue; int u = G[i][j].to - m; if (ans[u][0] == -1)ans[u][0] = i; else if (ans[u][1] == -1)ans[u][1] = i; } } for (int i = 0; i < n; i++) printf("%d %d\n", ans[i][0], ans[i][1]); return 0; }
Ural 1774 Barber of the Army of Mages 最大流
标签:
原文地址:http://www.cnblogs.com/HarryGuo2012/p/4728167.html