F. Flow Control
大致题意:一个有向图,无重边自环,每个点有一个值s,给每条边赋权,使得指向每个点的边权和 - 每个点指出去的边权和 = s,若没有满足的方案输出-1。
容易知道所有s的和必须为0,且此时一定有解。
如果我们把一个边的权值赋为0,那么这条边对整个结果没有影响。
于是我们可以从图中提取一棵树出来处理。
边权的值可以为负数,那么边其实可以看作无向边处理。
这样我们很容易在dfs时把边权赋值好。
//Author : Atlantis592
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
const int maxn = 200000 + 10;
int n, m, s[maxn], vis[maxn], ans[maxn];
vector<pii> G[maxn];
int dfs(int u)
{
vis[u] = 1; pii v;
for (int i = 0, d; i < G[u].size(); ++i)
{
v = G[u][i];
if (!vis[v.first]) {
d = dfs(v.first);
ans[abs(v.second)] = v.second > 0 ? d : -d;
s[u] += d;
}
}
return s[u];
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
{
scanf("%d", &s[i]);
s[0] += s[i];
}
if (s[0]) return puts("Impossible"), 0;
scanf("%d", &m);
for (int i = 1, u, v; i <= m; ++i)
{
scanf("%d%d", &u, &v);
G[u].push_back(pii(v, i));
G[v].push_back(pii(u, -i));
}
puts("Possible"); dfs(1);
for (int i = 1; i <= m; ++i)
printf("%d
", ans[i]);
return 0;
}