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;
}

 

posted @ 2014-04-21 17:35  wangyucheng  阅读(575)  评论(0编辑  收藏  举报