• 【BZOJ】3712: [PA2014]Fiolki


    http://www.lydsy.com/JudgeOnline/problem.php?id=3712

    题意:n个瓶子,第i个瓶子里又g[i]克物质。m次操作,第i次操作把第a[i]个瓶子的东西全部倒到第b[i]个瓶子里(保证之后不出现a[i])。k种反应,其中c[i]和d[i]反应,而且如果一个瓶子里有多种反应则优先反应靠前的。每次反应对答案贡献为min(g[i], g[i])*2(m<n<=200000, k<=500000)

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=200005, M=200005, nQ=500005;
    ll ans;
    int n, m, K, ihead[N+M], cnt, pos[N], g[N], dep[N+M], f[N+M][20], tot;
    struct E { int next, to; } e[(N+M)<<1];
    struct Q { int x, y, ff, dep, id; } q[nQ];
    bool cmp(const Q &a, const Q &b) {
    	return a.dep==b.dep?a.id<b.id:a.dep>b.dep;
    }
    void add(int x, int y) {
    	e[++cnt]=(E){ihead[x], y}; ihead[x]=cnt;
    	e[++cnt]=(E){ihead[y], x}; ihead[y]=cnt;
    }
    void dfs(int x) {
    	for(int i=1; i<=19; ++i) f[x][i]=f[f[x][i-1]][i-1];
    	for(int i=ihead[x]; i; i=e[i].next) if(e[i].to!=f[x][0]) { f[e[i].to][0]=x; dep[e[i].to]=dep[x]+1; dfs(e[i].to); }
    }
    int lca(int x, int y) {
    	if(dep[x]<dep[y]) swap(x, y);
    	int d=dep[x]-dep[y];
    	for(int i=19; i>=0; --i) if((d>>i)&1) x=f[x][i];
    	if(x==y) return x;
    	for(int i=19; i>=0; --i) if(f[x][i]!=f[y][i]) x=f[x][i], y=f[y][i];
    	return f[x][0];
    }
    int main() {
    	scanf("%d%d%d", &n, &m, &K);
    	for(int i=1; i<=n; ++i) pos[i]=i;
    	for(int i=1; i<=n; ++i) scanf("%d", &g[i]);
    	for(int i=1; i<=m; ++i) { int a, b; scanf("%d%d", &a, &b); int ff=n+i; add(pos[a], ff); add(pos[b], ff); pos[b]=ff; }	
    	for(int i=n+m; i>=1; --i) if(!f[i][0]) dfs(i);
    	for(int i=1; i<=K; ++i) { int a, b, ff; scanf("%d%d", &a, &b); ff=lca(a, b); if(!ff) continue; q[tot++]=(Q){a, b, ff, dep[ff], tot}; }
    	sort(q, q+tot, cmp);
    	for(int i=0; i<tot; ++i) {
    		int x=q[i].x, y=q[i].y;
    		int dec=min(g[x], g[y]);
    		g[x]-=dec; g[y]-=dec; ans+=dec;
    	}
    	printf("%lld
    ", ans<<1);
    	return 0;
    }
    

      

    居然是图论题啊orzzzzzzzzzzzz

    好题啊orzzzzzzzzz

    首先我们每次新建一个节点表示合并的两个瓶子(而题目中的条件表明了这是一个森林!),然后发现询问的话其实就是两个瓶子的lca!

    于是按lca的深度及其时间权值排序一下即可。

  • 相关阅读:
    点击有惊喜
    模态框案例
    DOM操作
    定时器
    函数和object
    shell 判断文件出现次数
    shell 判断路径
    shell 循环数组
    shell 判断为空打印
    shell 示例1 从1叠加到100
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4508357.html
Copyright © 2020-2023  润新知