# [UOJ]#61. 【UR #5】怎样更有力气

#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
{
int x;char c;
while((c=getchar())<'0'||c>'9');
for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=x*10+c-'0';
return x;
}
#define MN 300000
#define K 19
#define v(x,y) make_pair(min(x,y),max(x,y))
struct work{int x,y,w,id;}w[MN+5];
bool cmp(const work&a,const work&b){return a.w<b.w;}
int fa[K][MN+5],f[MN+5],d[MN+5],c[MN+5];
map<pair<int,int>,bool> mp[MN+5];
vector<int> v[MN+5],vv[MN+5];
int gf(int k){return f[k]?f[k]=gf(f[k]):k;}
int lca(int x,int y)
{
if(d[x]<d[y])swap(x,y);
int i=0,p=d[x]-d[y];
for(;p;p>>=1,++i)if(p&1)x=fa[i][x];
if(x==y)return x;
for(i=K;i--;)if(fa[i][x]!=fa[i][y])x=fa[i][x],y=fa[i][y];
return fa[0][x];
}
void merge(int a,int b)
{
if(vv[a].size()>vv[b].size())swap(a,b);
for(int i=0,x;i<vv[a].size();++i)
{
vv[c[x=vv[a][i]]=b].push_back(x);
if(c[fa[0][x]]==b)f[x]=fa[0][x];
for(int j=0;j<v[x].size();++j)if(c[v[x][j]]==b)f[v[x][j]]=x;
}
}
int main()
{
int n,m,p,i,j,t,a,b;long long ans=0;
for(j=1;j<K;++j)for(i=1;i<=n;++i)fa[j][i]=fa[j-1][fa[j-1][i]];
sort(w+1,w+m+1,cmp);
for(i=1;i<=n;++i)vv[i].push_back(c[i]=i);
for(i=1;i<=m;++i)
{
j=lca(w[i].x,w[i].y);
while(max(d[gf(w[i].x)],d[gf(w[i].y)])>d[j])
{
if(d[w[i].y]>d[w[i].x])swap(w[i].x,w[i].y);
for(a=w[i].x;d[a]>=d[j];a=fa[0][a])
{
if(c[a]==c[w[i].x]){a=gf(a);continue;}
if(mp[w[i].id][v(a,w[i].x)])continue;
ans+=w[i].w;merge(c[a],c[w[i].x]);
}
for(a=w[i].y;d[a]>=d[j];a=fa[0][a])
{
if(c[a]==c[w[i].x]){a=gf(a);continue;}
if(mp[w[i].id][v(a,w[i].x)])continue;
ans+=w[i].w;merge(c[a],c[w[i].x]);
}
w[i].x=fa[0][w[i].x];
}
}
printf("%lld",ans);
}

posted on 2017-09-13 17:40  ditoly  阅读(432)  评论(1编辑  收藏  举报