[dfs] Jzoj P5916 flow
题解
- 显然只有所有a的和为0的时候才有解
- 对于一个数字 x,将它子树的 a 累加起来,得到的就是 x 需要从它父 亲那里传过来或流出去
- 那么在判断一下正负就好了
代码
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #define N 200010 5 #define M 300010 6 using namespace std; 7 struct edge {long long to,from;}e[M*2]; 8 long long n,m,cnt=1,sum,a[N],vis[N],sz[N],head[N],f[M],x,y; 9 void insert(long long x,long long y) { e[++cnt].to=y; e[cnt].from=head[x]; head[x]=cnt; } 10 void dfs(long long x) 11 { 12 sz[x]=a[x],vis[x]=1; 13 for (long long i=head[x];i;i=e[i].from) 14 if (!vis[e[i].to]) 15 dfs(e[i].to),sz[x]+=sz[e[i].to],f[i/2]=((i&1)?1:-1)*sz[e[i].to]; 16 } 17 int main() 18 { 19 freopen("flow.in","r",stdin),freopen("flow.out","w",stdout); 20 scanf("%lld",&n); 21 for (long long i=1;i<=n;i++) scanf("%lld",&a[i]),sum+=a[i],a[i]=-a[i]; 22 if (sum!=0) { printf("Impossible\n"); return 0; } 23 printf("Possible\n"); 24 scanf("%lld",&m); 25 for (long long i=1;i<=m;i++) scanf("%lld%lld",&x,&y),insert(x,y),insert(y,x); 26 dfs(1); 27 for (long long i=1;i<=m;i++) printf("%lld\n",f[i]); 28 }