【AtCoder3611】Tree MST

Face questions

https://www.luogu.org/problem/AT3611

answer

Dotted, find Lagrange points each sub-tree, and all the trees within the handle side even to the point Lagrange point.

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#define N 200050
#define INF 1000000007LL
#define ri register int
using namespace std;
int n,m,w[N];
int siz[N],vis[N];
int f[N];
vector<int> to[N],len[N];

struct edge{
  int u,v;
  long long l;
  bool operator < (const edge &rhs) const {
    return l<rhs.l;
  }
} e[N*50];

int findrt(int x) {
  if (f[x]==x) return x;
  return f[x]=findrt(f[x]);
}

void findroot(int x,int ff,int &rt,int &rts,int tot) {
  int curs=0;
  siz[x]=1;
  for (ri i=0,l=to[x].size();i<l;i++) if (to[x][i]!=ff && !vis[to[x][i]]) {
    findroot(to[x][i],x,rt,rts,tot);
    siz[x]+=siz[to[x][i]];
    if (siz[to[x][i]]>curs) curs=siz[to[x][i]];
  }
  if (tot-siz[x]>curs) curs=tot-siz[x];
  if (curs<rts) rts=curs,rt=x;
}

void findP(int x,int ff,int &P,long long &pd,long long pred) {
  if (pred+w[x]<pd) pd=pred+w[x],P=x;
  for (ri i=0,l=to[x].size();i<l;i++) if (to[x][i]!=ff && !vis[to[x][i]]) {
    findP(to[x][i],x,P,pd,pred+len[x][i]);
  }
}

void link(int x,int ff,int P,long long pred) {
  e[++m]=(edge){x,P,pred+w[x]};
  for (ri i=0,l=to[x].size();i<l;i++) if (to[x][i]!=ff && !vis[to[x][i]]) {
    link(to[x][i],x,P,pred+len[x][i]);
  }
}

void tonji(int x,int ff,int &tot){
  tot++;
  for (ri i=0,l=to[x].size();i<l;i++) if (to[x][i]!=ff && !vis[to[x][i]]) tonji(to[x][i],x,tot);
}

void solve(int x){
  vis[x]=1;
  int p=-1;
  long long pd=INF*INF;
  findP(x,-1,p,pd,0LL);
  link(x,-1,p,pd);
  for (ri i=0,l=to[x].size();i<l;i++) if (!vis[to[x][i]]) {
    int tot=0;
    tonji(to[x][i],x,tot);
    int rt=-1,rts=tot;
    findroot(to[x][i],x,rt,rts,tot);
    solve(rt);
  }
}

int main() {
  int a,b,c;
  scanf("%d",&n);
  for (ri i=1;i<=n;i++) scanf("%d",&w[i]);
  for (ri i=1;i<n;i++) {
    scanf("%d %d %d",&a,&b,&c);
    to[a].push_back(b); len[a].push_back(c);
    to[b].push_back(a); len[b].push_back(c);
  };
  int rt=-1,rts=n;
  findroot(1,-1,rt,rts,n);
  solve(rt);
  sort(e+1,e+m+1);
  long long ans=0;
  for (ri i=1;i<=n;i++) f[i]=i;
  for (ri i=1;i<=m;i++) {
    int r1=findrt(e[i].u),r2=findrt(e[i].v);
    if (r1==r2) continue; 
    years + = e [i] .l; 
    f [r1] = r2; 
  } 
  Cout << age << endl;
  return  0 ; 
}

 

Guess you like

Origin www.cnblogs.com/shxnb666/p/11275664.html
MST
MST