题目链接
题目描述
You have to handle a very complex water distribution system. The system consists of nn
junctions and mm
pipes, ii
-th pipe connects junctions xixi
and yiyi
.
The only thing you can do is adjusting the pipes. You have to choose mm
integer numbers f1f1
, f2f2
, ..., fmfm
and use them as pipe settings. ii
-th pipe will distribute fifi
units of water per second from junction xixi
to junction yiyi
(if fifi
is negative, then the pipe will distribute |fi||fi|
units of water per second from junction yiyi
to junction xixi
). It is allowed to set fifi
to any integer from −2⋅109−2⋅109
to 2⋅1092⋅109
.
In order for the system to work properly, there are some constraints: for every i∈[1,n]i∈[1,n]
, ii
-th junction has a number sisi
associated with it meaning that the difference between incoming and outcoming flow for ii
-th junction must be exactly sisi
(if sisi
is not negative, then ii
-th junction must receive sisi
units of water per second; if it is negative, then ii
-th junction must transfer |si||si|
units of water per second to other junctions).
Can you choose the integers f1f1
, f2f2
, ..., fmfm
in such a way that all requirements on incoming and outcoming flows are satisfied?
题目翻译
现在有一幅图,节点由水管连接起来,现在每个水管里都有一些水流,请问能否使每个节点的输入或输出的水流大小等于指定的大小。
解题思路
首先,肯定得判断能不能构造。
那么我们怎么判断呢?
假设一条水管连通x和y两个点,那么假设这条水管内的水流量为a,从x到y,那么x的水流量应该-a,而y的水流量应该+a,显然,两个节点的水量的和应该使0,那么我们直接判断每个节点的水量之和是不是0就好了。
接下来就是构造了,每两个节点之间都可能有很多条路径能够到达,我们只取一条,也就是构造一棵树,然后从最底层向上推,推出每根水管的水量。
代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #include<map> 7 using namespace std; 8 const int maxn=400050; 9 int n,m,cnt=0; 10 struct nod{ 11 int t,val; 12 }; 13 vector<nod>v[maxn]; 14 int jun[maxn],ans[maxn]; 15 bool vis[maxn]; 16 map<int,int>ma[400050]; 17 inline void read(register int &x){ 18 int f=1; 19 x=0; register char ch=getchar(); 20 while(ch<‘0‘||ch>‘9‘){ 21 if(ch==‘-‘)f=-1; 22 ch=getchar(); 23 } 24 while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar(); 25 x=x*f; 26 } 27 inline void dfs(int now,int fa,int num){ 28 vis[now]=1; 29 int tot=0,flag=0; 30 for(register int i=0;i<v[now].size();i++){ 31 if(v[now][i].t==fa||vis[v[now][i].t])continue; 32 flag=1; 33 dfs(v[now][i].t,now,i); 34 tot+=v[now][i].val; 35 } 36 if(!flag){ 37 ans[ma[fa][now]]=jun[now]; 38 v[fa][num].val=jun[now]; 39 return; 40 } 41 ans[ma[fa][now]]=jun[now]+tot; 42 v[fa][num].val=jun[now]+tot; 43 } 44 int main(){ 45 read(n); 46 long long tot=0; 47 for(register int i=1;i<=n;i++){ 48 read(jun[i]); 49 tot+=jun[i]; 50 } 51 read(m); 52 register int f,t; 53 for(register int i=1;i<=m;i++){ 54 read(f),read(t); 55 ma[f][t]=i; 56 ma[t][f]=i; 57 nod temp; 58 temp.t=t,temp.val=0; 59 v[f].push_back(temp); 60 temp.t=f; 61 v[t].push_back(temp); 62 } 63 if(tot!=0){ 64 cout<<"Impossible"<<endl; 65 return 0; 66 } 67 nod temp; 68 temp.t=1; 69 v[0].push_back(temp); 70 dfs(1,0,0); 71 cout<<"Possible"<<endl; 72 for(register int i=1;i<=n;i++){ 73 printf("%d\n",ans[i]); 74 } 75 }
原文地址:https://www.cnblogs.com/Fang-Hao/p/9255907.html