CF990F Flow Control 题解
解题思路
一个很显然的结论:
- 当且仅当所有点的流量之和为 $0$ 时,存在解。
在得出这个结论后,我们可以先计算出 $\displaystyle \sum_{i=1}^n s_i$ 的值,然后判断一下是否为 $0$,如果不为 $0$,那么直接输出 Impossible 即可。
接下来讨论为 $0$ 的情况。根据上面的结论我们可以知道,如果图联通,那么一定满足这个结论,反之亦然。由此可得,我们可以删除若干条边,只要剩下的边可以构成一个联通图就可以了。这里考虑最简单的情况,即只保留 $n-1$ 条边,剩下的边构成一棵无根树,我们默认 $1$ 号节点为它的根节点。从根开始搜索,直到找到叶子节点,然后我们根据叶子节点的约束条件,计算它的父节点还需要流入或流出的水量,然后一层层往上更新即可,每次更新的时候同时处理出当前节点和它的父亲节点连边的流量。因为一条边的水量的正负由边的方向决定,所以我们还需要记录每一条边,可以用 map 来存储两个点之间的边的编号,按照输入中给的方向的边,编号为正,否则编号为负,这样在更新的时候就可以根据边的编号的正负来判断水流的方向,从而确定 $f_i$ 的正负。
时间复杂度 $O(n\log n)$。
AC 代码
#include<iostream>
#include<math.h>
#include<time.h>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include <map>
#define ll long long
inline void FileOpen(const char *infile,const char *outfile){
char *fileread=new char[1];
char *filewrite=new char[1];
fileread[0]=114,filewrite[0]=119;
freopen(infile,fileread,stdin);
freopen(outfile,filewrite,stdout);
}
inline void FileClose(){
char *fileread=new char[1];
char *filewrite=new char[1];
char *CONwrite=new char[3];
fileread[0]=114,filewrite[0]=119;
CONwrite[0]=67,CONwrite[1]=79,CONwrite[2]=78;
fclose(stdin);
fclose(stdout);
std::cin.clear();
std::cout.clear();
freopen(CONwrite,fileread,stdin);
freopen(CONwrite,filewrite,stdout);
}
#define N 200005
#define pii std::pair<int,int>
int n,m,s[N],f[N];
int fl[N],vis[N];
std::vector<int> edge[N];
std::map<pii,int> pos;
inline void dfs(int u,int fa){
fl[u]=s[u];vis[u]=1;
for(auto v:edge[u]){
if(v==fa) continue;
if(vis[v]) continue;
dfs(v,u);fl[u]+=fl[v];
}if(fl[u]==0) return;
int np=pos[{u,fa}];
if(np<0)
f[-np]=fl[u];
else f[np]=-fl[u];
}
inline void work(){
scanf("%d",&n);int sum=0;
for(register int i=1;i<=n;++i)
scanf("%d",&s[i]),sum+=s[i];
if(sum!=0){puts("Impossible");return;}
scanf("%d",&m);int u,v;
for(register int i=1;i<=m;++i){
scanf("%d%d",&u,&v);
edge[u].push_back(v);
edge[v].push_back(u);
pos[{u,v}]=i;
pos[{v,u}]=-i;
}dfs(1,0);puts("Possible");
for(register int i=1;i<=m;++i)
printf("%d\n",f[i]);
}signed main(){
srand(114514);
srand(rand());
srand(time(0));
work();system("pause");
}

浙公网安备 33010602011771号