bzoj 3206: [Apio2013]道路费用
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; #define N 110000 #define M 310000 #define K 120 #define inf 0x6fffffff typedef long long ll; struct P{ int x,y,w; int num; bool operator<(P a)const{ return w<a.w; } }w[M],c[M],w1[M]; int n,m,wn,k; int xx[30],yy[30]; int f[N],f2[N],ren[N]; ll s[N]; ll ans,rec; int wn1; int nn; int dn,dd[K]; int e[N],ne[N],v[N],cs[N]; bool been[K]; void add(int x,int y,int ww){ ne[++nn]=e[x],e[x]=nn,v[nn]=y,cs[nn]=ww; } 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]); } bool he(int x,int y){ int x1=get(x),y1=get(y); if(x1!=y1)return f[x1]=y1,1; return 0; } void he2(int x,int y){ int x1=get2(x),y1=get2(y); if(x1!=y1)f2[x1]=y1; } int dep[N],fa[N],cu[N]; ll S[N]; void dfs(int x){ S[x]=s[x]; for(int i=e[x];i;i=ne[i]){ if(fa[x]==v[i])continue; fa[v[i]]=x; cu[v[i]]=cs[i]; dep[v[i]]=dep[x]+1; dfs(v[i]); S[x]+=S[v[i]]; } } void geng(int x,int y,int 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=fa[x]; } } void dfs2(int x,int ff){ for(int i=e[x];i;i=ne[i]){ if(ff==v[i])continue; dfs2(v[i],x); if(w1[cs[i]].num)rec+=(ll)S[v[i]]*w1[cs[i]].w; } } void solv(int x){ rec=0,nn=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); for(int i=1;i<=dn;i++)f[dd[i]]=dd[i],e[dd[i]]=0,dep[dd[i]]=0,fa[dd[i]]=0,cu[dd[i]]=0; for(int i=1;i<=wn1;i++){ been[i]=0; if(he(w1[i].x,w1[i].y)){ been[i]=1; add(w1[i].x,w1[i].y,i); add(w1[i].y,w1[i].x,i); }else{ if(w1[i].w==-inf)return; } } dfs(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); } dfs2(f2[1],0); ans=max(ans,rec); } int main(){ scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=m;i++){ scanf("%d%d%d",&c[i].x,&c[i].y,&c[i].w); } for(int i=1;i<=n;i++)f[i]=i; 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]); w[++wn].x=xx[i],w[wn].y=yy[i],w[wn].num=i,w[wn].w=-inf; } 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); } for(int i=1;i<=n;i++){ scanf("%d",&ren[i]); s[get2(i)]+=ren[i]; } for(int i=1;i<=n;i++)if(f2[i]==i)dd[++dn]=i; for(int i=1;i<=wn;i++)if(f2[w[i].x]!=f2[w[i].y]){ w1[++wn1]=w[i]; w1[wn1].x=f2[w[i].x]; w1[wn1].y=f2[w[i].y]; } for(int i=0;i<(1<<k);i++)solv(i); cout<<ans; }