题目链接:
题意:给你一颗树,树中每条边有一权值c,对于从i节点到j节点的路径,其权值定义为该路径上边权值的最小值,于是问找到一个中心点,使得从该点到其他节点的路径权值和最大,求该最大值。思路;要使得权值和最大,容易想到对边进行从大到小排序,用一个sum来记录权值,cnt来记录节点个数,然后每次合并时取权值和较大的那个即可。
1 #include2 #include 3 #include 4 #include 5 using namespace std; 6 #define MAXN 200200 7 typedef long long LL; 8 int parent[MAXN]; 9 LL sum[MAXN];10 int cnt[MAXN];11 struct Edge{12 int u,v,w;13 }edge[MAXN];14 int n;15 16 void Initiate()17 {18 memset(sum,0,(n+2)*sizeof(sum[0]));19 for(int i=0;i<=n;i++){20 parent[i]=i;21 cnt[i]=1;22 }23 }24 25 int Find(int x)26 {27 if(x==parent[x])28 return x;29 parent[x]=Find(parent[x]);30 return parent[x];31 }32 33 void Union(int r1,int r2,LL w)34 {35 parent[r1]=r2;36 cnt[r2]+=cnt[r1];37 sum[r2]+=w;38 }39 40 int cmp(const Edge &p,const Edge &q)41 {42 return p.w>q.w;43 }44 45 int main()46 {47 // freopen("1.txt","r",stdin);48 while(~scanf("%d",&n))49 {50 Initiate();51 for(int i=0;i tmp2){62 Union(r2,r1,tmp1-sum[r1]);63 }else64 Union(r1,r2,tmp2-sum[r2]);65 }66 printf("%I64d\n",sum[Find(1)]);67 }68 return 0;69 }