开始看到的时候以为是道带权并查集,想了半天分钟实在不知道怎么维护
然后发现自己nc了
考虑到只是求一个方案而不是最优解
我们可以考虑建一颗搜索树
因为只需要满足就可以了
然后递归计算以每个点为子树的点所需要的水量
而且必然也只会有这么多的水从这个点流给子树
那就把这值赋给相连的边就可以了
#include<bits/stdc++.h>
using namespace std;
#define ll long long
inline int read(){
char ch=getchar();
int res=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return res*f;
}
const int N=200005,M=300005;
int n,m,adj[N],nxt[M<<1],to[M<<1],pos[M<<1],cnt=1;
long long tot,ans[M],a[N],val[M<<1];
bool vis[N];
inline void addedge(int u,int v,int i){
nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v,pos[cnt]=i;
nxt[++cnt]=adj[v],adj[v]=cnt,to[cnt]=u,pos[cnt]=i;
}
inline int dfs(int u,int fa){
vis[u]=true;
for(int e=adj[u];e;e=nxt[e]){
int v=to[e];
if(vis[v]||v==fa)continue;
dfs(v,u);
a[u]+=a[v];
val[e^1]+=a[v];
}
}
int main(){
n=read();
for(int i=1;i<=n;i++)a[i]=read(),tot+=a[i];
m=read();
for(int i=1;i<=m;i++){
int u=read(),v=read();addedge(u,v,i);
}
if(tot!=0){
cout<<"Impossible"<<'
';
return 0;
}
else cout<<"Possible"<<'
';
dfs(1,0);
for(int i=1;i<=cnt;i++){
if(i&1)ans[pos[i]]+=val[i];
else ans[pos[i]]-=val[i];
}
for(int i=1;i<=m;i++){
cout<<(ans[i])<<'
';
}
}