1. 程式人生 > >[bzoj3712][PA2014]Fiolki

[bzoj3712][PA2014]Fiolki

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