bzoj 3712: [PA2014]Fiolki
2017-09-22 08:31
204 查看
Description
化学家吉丽想要配置一种神奇的药水来拯救世界。
吉丽有n种不同的液体物质,和n个药瓶(均从1到n编号)。初始时,第i个瓶内装着g[i]克的第i种物质。吉丽需要执行一定的步骤来配置药水,第i个步骤是将第a[i]个瓶子内的所有液体倒入第b[i]个瓶子,此后第a[i]个瓶子不会再被用到。瓶子的容量可以视作是无限的。
吉丽知道某几对液体物质在一起时会发生反应产生沉淀,具体反应是1克c[i]物质和1克d[i]物质生成2克沉淀,一直进行直到某一反应物耗尽。生成的沉淀不会和任何物质反应。当有多于一对可以发生反应的物质在一起时,吉丽知道它们的反应顺序。每次倾倒完后,吉丽会等到反应结束后再执行下一步骤。
吉丽想知道配置过程中总共产生多少沉淀。
Input
第一行三个整数n,m,k(0<=m<n<=200000,0<=k<=500000),分别表示药瓶的个数(即物质的种数),操作步数,可以发生的反应数量。
第二行有n个整数g[1],g[2],…,g
(1<=g[i]<=10^9),表示初始时每个瓶内物质的质量。
接下来m行,每行两个整数a[i],bi,表示第i个步骤。保证a[i]在以后的步骤中不再出现。
接下来k行,每行是一对可以发生反应的物质c[i],di,按照反应的优先顺序给出。同一个反应不会重复出现。
Output
Sample Input
3 2 1
2 3 4
1 2
3 2
2 3
Sample Output
6
解题报告:
很容易想到:如果按操作建图,最后反应的顺序就是lca的深度,所以我们按照操作建好图,然后求出所有lca的深度,最后排个序就可以做了
那么问题来了:
如果先将3倒入1,再将2倒入1,1.2.3之间都可以反应,那么就不清楚反应顺序了,所以跟操作顺序也有很大关系,所以建图不能简单的直接从x连到y,需要新建一个节点,保证先输入的深度更大,那么就没有问题了.
化学家吉丽想要配置一种神奇的药水来拯救世界。
吉丽有n种不同的液体物质,和n个药瓶(均从1到n编号)。初始时,第i个瓶内装着g[i]克的第i种物质。吉丽需要执行一定的步骤来配置药水,第i个步骤是将第a[i]个瓶子内的所有液体倒入第b[i]个瓶子,此后第a[i]个瓶子不会再被用到。瓶子的容量可以视作是无限的。
吉丽知道某几对液体物质在一起时会发生反应产生沉淀,具体反应是1克c[i]物质和1克d[i]物质生成2克沉淀,一直进行直到某一反应物耗尽。生成的沉淀不会和任何物质反应。当有多于一对可以发生反应的物质在一起时,吉丽知道它们的反应顺序。每次倾倒完后,吉丽会等到反应结束后再执行下一步骤。
吉丽想知道配置过程中总共产生多少沉淀。
Input
第一行三个整数n,m,k(0<=m<n<=200000,0<=k<=500000),分别表示药瓶的个数(即物质的种数),操作步数,可以发生的反应数量。
第二行有n个整数g[1],g[2],…,g
(1<=g[i]<=10^9),表示初始时每个瓶内物质的质量。
接下来m行,每行两个整数a[i],bi,表示第i个步骤。保证a[i]在以后的步骤中不再出现。
接下来k行,每行是一对可以发生反应的物质c[i],di,按照反应的优先顺序给出。同一个反应不会重复出现。
Output
Sample Input
3 2 1
2 3 4
1 2
3 2
2 3
Sample Output
6
解题报告:
很容易想到:如果按操作建图,最后反应的顺序就是lca的深度,所以我们按照操作建好图,然后求出所有lca的深度,最后排个序就可以做了
那么问题来了:
如果先将3倒入1,再将2倒入1,1.2.3之间都可以反应,那么就不清楚反应顺序了,所以跟操作顺序也有很大关系,所以建图不能简单的直接从x连到y,需要新建一个节点,保证先输入的深度更大,那么就没有问题了.
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> #define RG register #define il inline #define iter iterator #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) using namespace std; const int N=800005,M=500005; int head ,num=0,to[N<<1],nxt[N<<1],n,a ,m,Q,dep ,fa ,top ; int son ,sz ,ids=0,col ; void link(int x,int y){nxt[++num]=head[x];to[num]=y;head[x]=num;} void dfs1(int x,int co){ int u;sz[x]=1;col[x]=co; for(int i=head[x];i;i=nxt[i]){ u=to[i];if(dep[u])continue; dep[u]=dep[x]+1;fa[u]=x; dfs1(u,co);sz[x]+=sz[u]; if(sz[u]>sz[son[x]])son[x]=u; } } void dfs2(int x,int tp){ top[x]=tp; if(son[x])dfs2(son[x],tp); for(int i=head[x];i;i=nxt[i]) if(to[i]!=fa[x] && to[i]!=son[x]) dfs2(to[i],to[i]); } struct node{ int x,y,id,lca; bool operator <(const node &pr)const{ if(dep[lca]!=dep[pr.lca])return dep[lca]>dep[pr.lca]; return id<pr.id; } }e[M]; int lca(int x,int y){ while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); x=fa[top[x]]; } if(dep[x]>dep[y])swap(x,y); return x; } int Fa ,du ; void work() { int x,y; scanf("%d%d%d",&n,&m,&Q); for(int i=1;i<=n;i++)scanf("%d",&a[i]),Fa[i]=i; for(int i=1;i<=m;i++){ scanf("%d%d",&x,&y); link(i+n,Fa[x]);link(Fa[y],i+n); link(Fa[x],i+n);link(i+n,Fa[y]); Fa[y]=i+n; } for(int i=n+m;i>=1;i--) if(!dep[i])dep[i]=1,dfs1(i,++ids),dfs2(i,i); for(int i=1;i<=Q;i++){ scanf("%d%d",&e[i].x,&e[i].y); if(col[e[i].x]!=col[e[i].y])continue; e[i].lca=lca(e[i].x,e[i].y); e[i].id=i; } sort(e+1,e+Q+1);long long ans=0,res; for(int i=1;i<=Q;i++){ x=e[i].x;y=e[i].y; if(col[x]!=col[y])continue; res=Min(a[x],a[y]);ans+=res<<1; a[x]-=res;a[y]-=res; } printf("%lld\n",ans); } int main() { work(); return 0; }
相关文章推荐
- BZOJ3712 [PA2014]Fiolki
- bzoj3712 [PA2014]Fiolki
- BZOJ 3712: [PA2014]Fiolki 思路题
- [bzoj3712][PA2014]Fiolki_倍增LCA
- 【bzoj3712】[PA2014]Fiolki
- BZOJ:3712: [PA2014]Fiolki
- 【PA2014】【BZOJ3712】Fiolki
- bzoj 3712: [PA2014]Fiolki
- BZOJ3712 PA2014Fiolki(kruskal重构树)
- bzoj 3712 [PA2014]Fiolki(LCA)
- BZOJ 3712: [PA2014]Fiolki
- bzoj 3712: [PA2014]Fiolki
- BZOJ 3712: [PA2014]Fiolki 倍增+想法
- 【BZOJ】3712: [PA2014]Fiolki
- 3712: [PA2014]Fiolki LCA 思路题
- 3712: [PA2014]Fiolki
- 3712: [PA2014]Fiolki(思路好题)
- 【暴力】bzoj3713 [PA2014]Iloczyn
- 【贪心】bzoj 3709:[PA2014]Bohater
- BZOJ 3709: [PA2014]Bohater