cf 304 Soldier and Traveling 网络流 + 记录流量情况
2017-08-27 16:49
686 查看
网络流 + 记录流量情况
题意: n个城市,每个城市有最初的卫兵ai,现在需要转移卫兵,第i个城市需要卫兵bi,每一个城市的卫兵可以转移到临近的城市,也就是距离为1的邻近城市,问是否可以转移到,如果可以输出YES并且输出转移情况。
思路:
根据题意和城市卫兵转移的性质,可以判断是网路流问题,但是因为有转移的限制所以需要思考如何建图。
根据限制,为了保证从ai状态到bi状态,把城市拆分为ai和bi状态,把有边的城市i和i+n建边cap为INF,i+n到t的cap为bi,再设置超级源点s。跑一次最大流即可。根据反向边的情况输出答案。
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue> using namespace std; const int maxn = 1005; const int INF = 0x3f3f3f3f; struct edge { int to,cap,rev; }; vector<edge>G[maxn]; int level[maxn],iter[maxn]; void add_edge(int from,int to,int cap) { int len1 = G[from].size(); int len2 = G[to].size(); G[from].push_back((edge){to,cap,len2}); G[to].push_back((edge){from,0,len1}); } 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(); int len = G[v].size(); for(int i = 0;i < len; 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; int len = G[v].size(); for(int &i = iter[v];i < len; 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,m,s,t; int a[maxn],b[maxn]; int ans[maxn][maxn]; int main(int argc, char const *argv[]) { // freopen("in.txt","r",stdin); scanf("%d%d",&n,&m); s = 0,t = 2*n+1; int sum1 = 0 ,sum2 = 0; for(int i = 1;i <= n; i++) { int temp; scanf("%d",&temp); sum1 += temp; add_edge(s,i,temp); a[i] = temp; add_edge(i,i+n,INF); } for(int i = 1;i <= n; i++) { int temp; scanf("%d",&temp); sum2 += temp; add_edge(i+n,t,temp); b[i] = temp; } while(m--) { int u,v; scanf("%d%d",&v,&u); add_edge(v,u+n,INF); add_edge(u,v+n,INF); } int ans1 = max_flow(s,t); if(sum1 != sum2) { printf("NO\n"); return 0; } if(ans1 != sum1) { printf("NO\n"); return 0; } else { printf("YES\n"); for(int i = 1;i <= n; i++) { int Size = G[i].size(); for(int j = 0;j < Size; j++) { edge e = G[i][j]; if(e.to == 0) continue; ans[i][e.to-n] = G[e.to][e.rev].cap; } } for(int i = 1;i <= n; i++) 4000 { for(int j = 1;j <= n; j++) { printf("%d ",ans[i][j]); } printf("\n"); } } return 0; }
相关文章推荐
- 【CF】304 E. Soldier and Traveling
- Codeforces 546E - Soldier and Traveling (网络流输出流量)
- 网络流(最大流) CodeForces 546E:Soldier and Traveling
- E. Soldier and Traveling(CF546E) Codeforces Round #304 (Div. 2)
- Codeforces Round #304 (Div. 2)E. Soldier and Traveling 网络流
- CodeForces 546E - Soldier and Traveling(最大流+输出边流量)
- CF Soldier and Traveling(最大流SAP)拆点法
- Codeforces Round #304 (Div. 2)E. Soldier and Traveling 网络流
- Codeforces 546E - Soldier and Traveling (最大流)
- CF 546A-Soldier and Bananas
- codeforce 304 B. Soldier and Badges
- CF 546 B. Soldier and Badges
- Codeforces 546 E Soldier and Traveling【最大流Dinic+判断残余网络】
- Codeforces Round #304 (Div. 2)C. Soldier and Cards(STL+模拟)
- CF 453B(Little Pony and Harmony Chest-数列最小加减1更改方案,满足任意2数互质-位运算dp+最坏情况分析+记忆化搜索)
- Codeforces Round #304 (Div. 2) E. Soldier and Traveling 最大流
- Codeforces Round #304 (Div. 2)-E. Soldier and Traveling
- Soldier and Traveling
- Codeforces Round #304 (Div. 2) E. Soldier and Traveling
- CF Soldier and Badges (贪心)