首页 > 其他 > 详细

[bzoj3712][PA2014]Fiolki

时间:2018-08-20 16:17:25      阅读:29      评论:0      收藏:0      [点我收藏+]

标签:math   lib   pro   its   num   lca   register   iomanip   com   

description

题面

data range

\[ 0\le m<n\le 200000,0\le k\le 500000\]

solution

之前本人一直煞笔地思考暴力是否可行

考虑按照操作关系直接构树,之后按照每个反应中两点在树上的\(lca\)深度排序

最后依次考虑每个反应即可

虽然说建出来的也是个\(Kruskal\)重构树

code

没有按质合并的并查集都能过

#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<ctime>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define FILE "a"
#define mp make_pair
#define pb push_back
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-10;
const int mod=1e9+7;
const int N=400010;
const int M=500010;
const dd pi=acos(-1);
const int inf=2147483645;
const ll INF=1e18+1;
const ll P=100000;
il ll read(){
    RG ll data=0,w=1;RG char ch=getchar();
    while(ch!=‘-‘&&(ch<‘0‘||ch>‘9‘))ch=getchar();
    if(ch==‘-‘)w=-1,ch=getchar();
    while(ch<=‘9‘&&ch>=‘0‘)data=data*10+ch-48,ch=getchar();
    return data*w;
}

il void file(){
    srand(time(NULL)+rand());
    freopen(FILE".in","r",stdin);
    freopen(FILE".out","w",stdout);
}

int num,n,m,k,g[N],t;ll ans;
int fa[N],f[20][N];
int find(int x){return fa[x]?fa[x]=find(fa[x]):x;}
int dep[N],RT;
int head[N],nxt[N],to[N],cnt;
il void add(int u,int v){
    to[++cnt]=v;
    nxt[cnt]=head[u];
    head[u]=cnt;
}
void dfs(int u,int ff){
    f[0][u]=ff;dep[u]=dep[ff]+1;
    for(RG int i=1;f[i-1][f[i-1][u]];i++)f[i][u]=f[i-1][f[i-1][u]];
    for(RG int i=head[u];i;i=nxt[i]){
        RG int v=to[i];dfs(v,u);
    }
}
struct edge{int u,v,id,d;}E[M];
bool cmp(edge x,edge y){if(x.d==y.d)return x.id<y.id;return x.d>y.d;}
il int lca(int u,int v){
    if(dep[u]<dep[v])swap(u,v);
    RG int d=dep[u]-dep[v];
    for(RG int i=19;~i;i--)if(d&(1<<i))u=f[i][u];
    if(u==v)return u;
    for(RG int i=19;~i;i--)
        if(f[i][u]!=f[i][v])u=f[i][u],v=f[i][v];
    if(u==v)return u;
    return f[0][u];
}

int main()
{
    num=n=read();m=read();k=read();
    for(RG int i=1;i<=n;i++)g[i]=read();
    for(RG int i=1,a,b;i<=m;i++){
        a=read();b=read();a=find(a);b=find(b);
        num++;fa[a]=fa[b]=num;add(num,a);add(num,b);
    }
    for(RG int i=1;i<=n+n;i++)if(!fa[i])dfs(i,0);
    for(RG int i=1,a,b;i<=k;i++){
        a=read();b=read();if(find(a)!=find(b))continue;
        E[++t]=(edge){a,b,i,dep[lca(a,b)]};
    }
    sort(E+1,E+t+1,cmp);
    for(RG int i=1,s;i<=t;i++){
        s=min(g[E[i].u],g[E[i].v]);
        g[E[i].u]-=s;g[E[i].v]-=s;ans+=2ll*s;
    }
    printf("%lld\n",ans);
    return 0;
}

[bzoj3712][PA2014]Fiolki

标签:math   lib   pro   its   num   lca   register   iomanip   com   

原文:https://www.cnblogs.com/cjfdf/p/9506072.html

(0)
(0)
   
举报
评论 一句话评论(0
0条  
登录后才能评论!
© 2014 bubuko.com 版权所有 鲁ICP备09046678号-4
打开技术之扣,分享程序人生!
             

鲁公网安备 37021202000002号