随笔
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; #define N 120000 typedef long long ll; #define M 410000 #define inf 0x6fffffff #define K 180 int f[N],f2[N],ren[N],di[N],dn; int n,m,k; int get(int x){ return f[x]==x?x:f[x]=get(f[x]); } int get2(int x){ return f2[x]==x?x:f2[x]=get2(f2[x]); } struct P{ int x,y; ll w; int bx,by; int num; bool operator<(P a)const{ return w<a.w; } }c[M],w[M],w1[M]; int xx[K],yy[K]; int e[M],ne[M*2],v[M*2]; ll ww[M*2]; int nn,wn,wn1; int rank[N],sa[K],op; ll dis[K][K]; ll ph[K]; int dep[N],fath[N]; ll up[N]; int e2[N],ne2[K],v2[K],tot; int w2[K],cu[N]; void add2(int x,int y,int z){ ne2[++tot]=e2[x],e2[x]=tot,v2[tot]=y,w2[tot]=z; } ll ans=-inf,s[N]; bool been[K]; void add(int x,int y,ll z){ ne[++nn]=e[x],e[x]=nn,v[nn]=y,ww[nn]=z; } bool he(int x,int y){ int x1=get(x),y1=get(y); if(x1==y1)return 0; return f[x1]=y1,1; } void he2(int x,int y){ int x1=get2(x),y1=get2(y); if(x1!=y1)f2[x1]=y1; } ll DIS(int x,int y){ ll ans=0; while(x!=y){ if(dep[x]<dep[y])swap(x,y); ans+=up[x]; x=fath[x]; } return ans; } ll S[N]; void df(int x){ S[x]=s[x]; for(int i=e2[x];i;i=ne2[i]){ if(fath[x]==v2[i])continue; fath[v2[i]]=x; cu[v2[i]]=w2[i]; dep[v2[i]]=dep[x]+1; df(v2[i]); S[x]+=S[v2[i]]; } } void geng(int x,int y,ll z){ while(x!=y){ if(dep[x]<dep[y])swap(x,y); if(w1[cu[x]].num){ if(w1[cu[x]].w==-inf)w1[cu[x]].w=z; else w1[cu[x]].w=min(w1[cu[x]].w,z); } x=fath[x]; } } ll rec; void dfs3(int x,int fa,ll len){ int fr,j,p,l2,pp; if(x==f2[1])fr=1; else fr=(w1[cu[x]].x==x?w1[cu[x]].bx:w1[cu[x]].by); for(int i=e2[x];i;i=ne2[i]){ j=v2[i]; if(fa==j)continue; if(w1[w2[i]].x==j) p=w1[w2[i]].bx,pp=p=w1[w2[i]].by; else p=w1[w2[i]].by,pp=w1[w2[i]].bx; l2=len+dis[rank[pp]][rank[fr]]+w1[w2[i]].w; rec+=l2*S[j]+ph[rank[p]]; dfs3(j,x,l2); } } ll solv(int x){ tot=0,rec=0; for(int i=1;i<=wn1;i++){ if(w1[i].num){ if(x&(1<<(w1[i].num-1))){ w1[i].w=-inf; }else{ w1[i].w=inf; } } } sort(w1+1,w1+wn1+1); int q; for(int i=1;i<=dn;i++)q=di[i],f[q]=q,e2[q]=0,dep[q]=0,fath[q]=0,cu[q]=0; for(int i=1;i<=wn1;i++){ been[i]=0; if(he(w1[i].x,w1[i].y)){ been[i]=1; add2(w1[i].x,w1[i].y,i); add2(w1[i].y,w1[i].x,i); } } df(f2[1]); for(int i=1;i<=wn1;i++)if(!been[i]&&w1[i].w!=inf){ geng(w1[i].x,w1[i].y,w1[i].w); } rec+=ph[rank[1]]; dfs3(f2[1],0,0); ans=max(ans,rec); } void dfs(int x,int fa){ for(int i=e[x];i;i=ne[i]){ if(v[i]==fa)continue; dep[v[i]]=dep[x]+1; up[v[i]]=ww[i]; fath[v[i]]=x; dfs(v[i],x); } } ll bb[N],siz[N]; void dfs2(int x,int fa){ siz[x]=ren[x]; bb[x]=0; for(int i=e[x];i;i=ne[i]){ if(v[i]==fa)continue; dfs2(v[i],x); siz[x]+=siz[v[i]]; bb[x]+=bb[v[i]]+siz[v[i]]*ww[i]; } } int main(){ scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++)f[i]=i; for(int i=1;i<=m;i++)scanf("%d%d%lld",&c[i].x,&c[i].y,&c[i].w); sort(c+1,c+m+1); for(int i=1;i<=m;i++)if(he(c[i].x,c[i].y))w[++wn]=c[i]; for(int i=1;i<=k;i++)scanf("%d%d",&xx[i],&yy[i]); for(int i=1;i<=n;i++)scanf("%d",&ren[i]); for(int i=1;i<=k;i++){ w[++wn].x=xx[i]; w[wn].y=yy[i]; w[wn].w=-inf; w[wn].num=i; } sort(w+1,w+wn+1); for(int i=1;i<=n;i++)f[i]=i,f2[i]=i; for(int i=1;i<=wn;i++){ if(he(w[i].x,w[i].y)){ if(!w[i].num){ he2(w[i].x,w[i].y); add(w[i].x,w[i].y,w[i].w); add(w[i].y,w[i].x,w[i].w); } } } for(int i=1;i<=n;i++)s[get2(i)]+=ren[i]; for(int i=1;i<=n;i++)if(f2[i]==i)dfs(i,0),di[++dn]=i; for(int i=1;i<=wn;i++)if(get2(w[i].x)!=get2(w[i].y)){ w1[++wn1]=w[i]; w1[wn1].bx=w[i].x; w1[wn1].by=w[i].y; w1[wn1].x=f2[w[i].x]; w1[wn1].y=f2[w[i].y]; if(!rank[w[i].x]){ sa[++op]=w[i].x; rank[w[i].x]=op; } if(!rank[w[i].y]){ sa[++op]=w[i].y; rank[w[i].y]=op; } } if(!rank[1]){ sa[++op]=1; rank[1]=op; } for(int i=1;i<=op;i++){ dfs2(sa[i],0); ph[i]=bb[sa[i]]; for(int j=i+1;j<=op;j++)if(f2[sa[i]]==f2[sa[j]])dis[j][i]=dis[i][j]=DIS(sa[i],sa[j]); } for(int i=0;i<(1<<k);i++)solv(i); cout<<ans; }