zoukankan      html  css  js  c++  java
  • Codeforces990F——Flow Control

    传送门

    开始看到的时候以为是道带权并查集,想了半天分钟实在不知道怎么维护

    然后发现自己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])<<'
    ';
        }
    }
    
    
  • 相关阅读:
    P1338 末日的传说
    P1364医院设置
    线程
    进程通信
    CentOS设置中文
    C++快读讲解
    迭代加深搜索
    P1118 [USACO06FEB]Backward Digit Sums G/S
    N皇后问题
    RMQ区间最值查询
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366406.html
Copyright © 2011-2022 走看看