【CodeForces】990F Flow Control

题目链接

Luogu & CodeForces

题目描述

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

时间: 2024-11-03 21:45:09

【CodeForces】990F Flow Control的相关文章

【CF708D】Incorrect Flow 最小费用可行流

[CF708D]Incorrect Flow 题意:给你一个点数为n,边数为m的流网络,每条边有一个容量c和流量f,这个网络可能是不合法的.你可以花费1的代价使c或f减少或增加1,可以修改无限次.你不需要使流量最大,你只需要花费最少的代价把原图改造成一个合法的网络. $n,m\le 100,c,f\le 10^6$ 题解:我们用有上下界的费用流来解决这个问题. 对于一条边a->b,如果c>f,则我们从a到b连一条下界和上界都是f,费用为0的边:因为可以减少流量,所以连一条从b到a,容量为f,费

【codeforces】【比赛题解】#854 CF Round #433 (Div.2)

cf一如既往挺丧 看丧题点我! [A]分数 Petya是数学迷,特别是有关于分数的数学.最近他学了所谓一个分数被叫做"真分数"当且仅当其分子小于分母,而一个分数被叫做"最简分数"当且仅当其分子分母互质.在闲暇时间,Petya在用计算器研究:如何把最简真分数转换为小数等问题.有一天他不小心把除号(÷)按成了加号(+),导致他得到了分子与分母的和.Petya想要得到他原来的分数,但他很快发现这不是唯一的.所以现在他想要知道最大的最简真分数使得其分子与分母的和为n. 输入

【CodeForces】835D Palindromic characteristics

[算法]区间DP [题解]涉及回文问题的区间DP都可以用类似的写法,就是h[i][j]表示i~j是否回文,然后就可以O(1)判断回文了. f[i][j]=k表示该字符串是k-th字符串,因为首先要求回文,既然回文那么左半边和右半边就肯定一样了. #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=5010; int f[maxn][maxn]

【codeforces】【比赛题解】#849 CF Round #431 (Div.2)

cf的比赛越来越有难度了--至少我做起来是这样. 先看看题目吧:点我. 这次比赛是北京时间21:35开始的,算是比较良心. [A]奇数与结束 "奇数从哪里开始,又在哪里结束?梦想从何处起航,它们又是否会破灭呢?" 给定一个长度为n的序列.确定能不能将序列分成奇数个长度为奇数的非空字串,而且这其中每个子串以奇数开头,以奇数结尾.可以只分成一个(1也是奇数). 输入 第一行一个正整数n,表示序列长度. 第二行n个整数,表示序列中的元素. 输出 输出"Yes"或"

【CodeForces】841C. Leha and Function(Codeforces Round #429 (Div. 2))

[题意]定义函数F(n,k)为1~n的集合中选择k个数字,其中最小数字的期望. 给定两个数字集A,B,A中任意数字>=B中任意数字,要求重组A使得对于i=1~n,sigma(F(Ai,Bi))最大. [算法]数学结论+数学期望+排序 [题解]很无奈,这题放在div2 C,难以推导的期望公式,广为人知的结论,容易观察样例得出的做法,都体现了这道题的不合理性. F(n,k)=(n+1)/(k+1) 公式推导可能触及我的知识盲区了QAQ 得到公式后,显然要求k尽可能小,n尽可能大,经验告诉我们随着两数

【CodeForces】585 E. Present for Vitalik the Philatelist

[题目]E. Present for Vitalik the Philatelist [题意]给定n个数字,定义一种合法方案为选择一个数字Aa,选择另外一些数字Abi,满足?gcd(Aa,Abi)=1,且gcd(Ab1...Abx)≠1,求方案数取模1e9+7.2<=n<=5*10^5,2<=ai<=10^7. [算法]数论,计数问题 [题解]

【CodeForces】578 C. Weakness and Poorness

[题目]C. Weakness and Poorness [题意]给定含n个整数的序列ai,定义新序列为ai-x,要使新序列的最大子段和绝对值最小,求实数x.n<=2*10^5. [算法]二分||三分||计算几何(凸包) [题解]Editorial 令正数最大子段和为A,负数最大子段和为B,绝对值是max(A,B).当x从小到大变化时,A由大变小,B由小变大. 容易发现这是一个下凸函数,可以用三分法求解. 但是,这道题卡精度(-11会WA,-12会T),解决方法是根据复杂度把循环次数卡到极限而不

【CodeForces】F. Letters Removing

[题目]F. Letters Removing [题意]给定只含小写字母.大写字母和数字的字符串,每次给定一个范围要求删除[l,r]内的字符c(l和r具体位置随删除变动),求m次操作后的字符串.n<=2*10^5. [算法]树状数组+平衡树(set) [题解]因为坐标是序列变动后的,动态坐标可以转化为找到第l个存在的数字到第r个存在的数字之间的范围. 将序列中存在记为1,删除记为0,转化为找前缀和恰好为l和r的位置,这是树状数组的经典操作,详见这篇题解介绍的方法(简单的排名功能) 找到l和r在原

【CodeForces】D. Roads in Yusland

[题目]D. Roads in Yusland [题意]给定n个点的树,m条严格从下往上的路径,每条路径代价ci,求最少代价使得路径覆盖所有边.n,m<=3*10^5,ci<=10^9. [算法]树形DP+线段树||可并堆 [题解]