Educational Codeforces Round 45 (Rated for Div. 2) F - Flow Control
给你一个有向图,要求你给每条边设置流量,使得所有点的流量符合题目给出的要求。
思路:只有在所有点的流量和为0时有解,因为增加一条边的值不会改变所有点的总流量和,
所以我们dfs回溯的时候构造就好了, 其他边设为0。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int, int> using namespace std; const int N = 2e5 + 7; const int M = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 +7; int head[N], s[N], ans[N], flow[N], tot, n, m, sum; bool vis[N]; struct Edge { int to, id, nx; } edge[N << 1]; void add(int u, int v, int id) { edge[tot].to = v; edge[tot].id = id; edge[tot].nx = head[u]; head[u] = tot++; } void dfs(int u, int p, int id) { vis[u] = true; for(int i = head[u]; ~i; i = edge[i].nx) { int v = edge[i].to; if(vis[v]) continue; dfs(v, u, i); } if(flow[u] != s[u]) { int ret = abs(s[u] - flow[u]); if(flow[u] < s[u]) { flow[u] = 0; flow[p] -= ret; if(id & 1) { ans[edge[id].id] = -ret; } else { ans[edge[id].id] = ret; } } else { flow[u] = 0; flow[p] += ret; if(id & 1) { ans[edge[id].id] = ret; } else { ans[edge[id].id] = -ret; } } } } int main() { memset(head, -1, sizeof(head)); scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%d", &s[i]); sum += s[i]; } scanf("%d", &m); for(int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); add(u, v, i); add(v, u, i); } if(!sum) { dfs(1, 0, -1); puts("Possible"); for(int i = 1; i <= m; i++) { printf("%d\n", ans[i]); } } else { puts("Impossible"); } return 0; } /* */