codeforces 546E. Soldier and Traveling 网络流

题目链接

给出n个城市, 以及初始时每个城市的人数以及目标人数。初始时有些城市是相连的。 每个城市的人只可以待在自己的城市或走到与他相邻的城市, 相邻, 相当于只能走一条路。

如果目标状态不可达, 输出no, 否则输出每个城市的人都是怎么走的, 比如第一个城市有2个人走到了第二个城市, 1个人留在了第一个城市, 那么输出的第一行前两个数就是1, 2。

很明显的网络流, 输出那里写了好久...

首先判断能否可达, 如果初始状态的人数与目标状态不一样, 一定不可达, 其次, 如果建完图跑网络流的结果与所有目标城市人数的和不一样, 也不可达。

建图的话, 将一个城市拆成两个点, (u, u') 中间连边inf, 说明可以随便走, 源点和u相连, 权值为初始状态人数, u'与汇点相连, 人数为目标状态人数。 如果两个城市之间有路相连, 那么加边(u, v'), (v, u'), 权值为inf。

每个城市的人是怎么走的, 应该看反向边的流量, 如果边(v', u)的权值为x, 那么ans[u][v] = x。

具体看代码。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define pb(x) push_back(x)
  4 #define ll long long
  5 #define mk(x, y) make_pair(x, y)
  6 #define lson l, m, rt<<1
  7 #define mem(a) memset(a, 0, sizeof(a))
  8 #define rson m+1, r, rt<<1|1
  9 #define mem1(a) memset(a, -1, sizeof(a))
 10 #define mem2(a) memset(a, 0x3f, sizeof(a))
 11 #define rep(i, a, n) for(int i = a; i<n; i++)
 12 #define ull unsigned long long
 13 typedef pair<int, int> pll;
 14 const double PI = acos(-1.0);
 15 const double eps = 1e-8;
 16 const int mod = 1e9+7;
 17 const int inf = 1061109567;
 18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
 19 const int maxn = 2e5;
 20 int q[maxn*2], head[maxn*2], dis[maxn/10], s, t, num, vis[105], val[205][205];
 21 struct node
 22 {
 23     int to, nextt, c;
 24     node(){}
 25     node(int to, int nextt, int c):to(to), nextt(nextt), c(c){}
 26 }e[maxn*2];
 27 void init() {
 28     num = 0;
 29     mem1(head);
 30 }
 31 void add(int u, int v, int c) {
 32     e[num] = node(v, head[u], c); head[u] = num++;
 33     e[num] = node(u, head[v], 0); head[v] = num++;
 34 }
 35 int bfs() {
 36     mem(dis);
 37     dis[s] = 1;
 38     int st = 0, ed = 0;
 39     q[ed++] = s;
 40     while(st<ed) {
 41         int u = q[st++];
 42         for(int i = head[u]; ~i; i = e[i].nextt) {
 43             int v = e[i].to;
 44             if(!dis[v]&&e[i].c) {
 45                 dis[v] = dis[u]+1;
 46                 if(v == t)
 47                     return 1;
 48                 q[ed++] = v;
 49             }
 50         }
 51     }
 52     return 0;
 53 }
 54 int dfs(int u, int limit) {
 55     if(u == t) {
 56         return limit;
 57     }
 58     int cost = 0;
 59     for(int i = head[u]; ~i; i = e[i].nextt) {
 60         int v = e[i].to;
 61         if(e[i].c&&dis[v] == dis[u]+1) {
 62             int tmp = dfs(v, min(limit-cost, e[i].c));
 63             if(tmp>0) {
 64                 e[i].c -= tmp;
 65                 e[i^1].c += tmp;
 66                 cost += tmp;
 67                 if(cost == limit)
 68                     break;
 69             } else {
 70                 dis[v] = -1;
 71             }
 72         }
 73     }
 74     return cost;
 75 }
 76 int dinic() {
 77     int ans = 0;
 78     while(bfs()) {
 79         ans += dfs(s, inf);
 80     }
 81     return ans;
 82 }
 83 int main()
 84 {
 85     int n, m, x, y, sum = 0, tmp = 0;
 86     cin>>n>>m;
 87     init();
 88     s = 0, t = n*2+1;
 89     for(int i = 1; i<=n; i++) {
 90         scanf("%d", &x);
 91         add(s, i, x);
 92         tmp += x;
 93     }
 94     for(int i = 1; i<=n; i++) {
 95         scanf("%d", &x);
 96         add(i+n, t, x);
 97         sum += x;
 98         add(i, i+n, inf);
 99     }
100     while(m--) {
101         scanf("%d%d", &x, &y);
102         add(x, y+n, inf);
103         add(y, x+n, inf);
104     }
105     int ans = dinic();
106     if(ans != sum||sum!=tmp) {
107         cout<<"NO"<<endl;
108         return 0;
109     }
110     cout<<"YES"<<endl;
111     for(int u = 1; u<=n; u++) {
112         for(int i = head[u]; ~i; i = e[i].nextt) {
113             int v = e[i].to;
114             if(v>n) {
115                 val[u][v-n] = e[i^1].c;         //反向边流量
116             }
117         }
118     }
119     for(int i = 1; i<=n; i++) {
120         for(int j = 1; j<=n; j++) {
121             cout<<val[i][j]<<" ";
122         }
123         cout<<endl;
124     }
125     return 0;
126 }

 

posted on 2015-12-13 15:35  yohaha  阅读(534)  评论(0编辑  收藏  举报

导航