zoukankan      html  css  js  c++  java
  • BZOJ3712: [PA2014]Fiolki

    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[n](1<=g[i]<=10^9),表示初始时每个瓶内物质的质量。
    接下来m行,每行两个整数a[i],b[i](1<=a[i],b[i]<=n,a[i]≠b[i]),表示第i个步骤。保证a[i]在以后的步骤中不再出现。
    接下来k行,每行是一对可以发生反应的物质c[i],d[i](1<=c[i],d[i]<=n,c[i]≠d[i]),按照反应的优先顺序给出。同一个反应不会重复出现。

    Sample Input

    3 2 1
    2 3 4
    1 2
    3 2
    2 3

    Sample Output

    6
    不是很会做,想了很多数据结构都不是很资瓷
    看了一发路牌:LCA考虑LCA做法
    对于合并两个瓶子,就看做一个新节点连向这两个节点,最终会构成一棵树
    然后对于每对关系,发生的一定是两个节点在同一颗树里,先后顺序按照LCA的深度判定
    建图时跑了个并查集维护
    代码如下:
    //MT_LI
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    int n,m,T;
    struct node{
        int x,y,next;
    }a[410000];int len,last[410000];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    int f[410000][21],dep[410000];
    int g[210000];int bin[21];
    int fa[410000];
    int v[410000];
    void dfs(int x,int fa)
    {
        v[x]=1;
        dep[x]=dep[fa]+1;f[x][0]=fa;
        for(int i=1;bin[i]<=dep[x];i++)f[x][i]=f[f[x][i-1]][i-1];
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fa)dfs(y,x);
        }
    }
    int findfa(int x)
    {
        if(fa[x]!=x)fa[x]=findfa(fa[x]);
        return fa[x];
    }
    int LCA(int x,int y)
    {
        if(dep[x]<dep[y])swap(x,y);
        for(int i=19;i>=0;i--)
            if(dep[x]-bin[i]>=dep[y])
                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];
    }
    struct Q{
        int x,y,dep,id;
    }q[510000];
    typedef long long ll;
    bool cmp(Q a,Q b){return a.dep!=b.dep?a.dep>b.dep:a.id<b.id;}
    int main()
    {
        bin[0]=1;
        for(int i=1;i<=19;i++)bin[i]=bin[i-1]<<1;
        len=0;memset(last,0,sizeof(last));
        scanf("%d%d%d",&n,&m,&T);
        for(int i=1;i<=n;i++)fa[i]=i;
        for(int i=1;i<=n;i++)scanf("%d",&g[i]);
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            int fx=findfa(x),fy=findfa(y);
            n++;ins(n,fx);ins(n,fy);fa[n]=n;
            fa[fx]=n,fa[fy]=n;
        }    
        memset(v,0,sizeof(v));
        for(int i=1;i<=n;i++)
            if(!v[i])
            {
                int root=findfa(i);
                dep[root]=0;dfs(root,0);
            }
        for(int i=1;i<=T;i++)
        {
            scanf("%d%d",&q[i].x,&q[i].y);
            if(findfa(q[i].x)!=findfa(q[i].y)){q[i].dep=-1<<30;continue;}
            q[i].dep=dep[LCA(q[i].x,q[i].y)];q[i].id=i;
        }
        sort(q+1,q+1+T,cmp);
        ll ans=0ll;
        for(int i=1;q[i].dep!=-1<<30&&i<=T;i++)
        {
            int tt;
            ans+=2*(tt=min(g[q[i].x],g[q[i].y]));
            g[q[i].x]-=tt,g[q[i].y]-=tt;
        }
        printf("%lld
    ",ans);
        return 0;    
    }
  • 相关阅读:
    Objective-C NSFileManager 文件管理总结
    ScrollView在RelativeLayout失效问题
    解决myeclipse中struts2 bug问题包的替换问题
    SOA究竟是个啥
    Flash--元件和实例
    MyEclipse中加入web项目到tomcat
    [C]if (CONDITION)语句中CONDITION的情况
    GTK经常使用控件之笔记本控件( GtkNotebook )
    org.apache.solr.handler.dataimport.DataImportHandlerException: Data Config problem: 对实体 &quot;characterEn
    Android自动测试之Monkey工具
  • 原文地址:https://www.cnblogs.com/MT-LI/p/9892834.html
Copyright © 2011-2022 走看看