題面php
\[ 0\le m<n\le 200000,0\le k\le 500000\]ios
以前本人一直煞筆地思考暴力是否可行c++
考慮按照操做關係直接構樹,以後按照每一個反應中兩點在樹上的\(lca\)深度排序spa
最後依次考慮每一個反應便可code
雖說建出來的也是個\(Kruskal\)重構樹排序
沒有按質合併的並查集都能過ip
#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; }