Educational Codeforces Round 45 (Rated for Div. 2)

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\n", ans[i]);
	return 0;
}

posted on 2018-06-15 16:51  No_CE_in_Vegetable  阅读(91)  评论(0编辑  收藏  举报

导航