1737 配对

1737 配对

基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题

给出一棵n个点的树,将这n个点两两配对,求所有可行的方案中配对两点间的距离的总和最大为多少。

Input

一个数n(1<=n<=100,000,n保证为偶数) 接下来n-1行每行三个数x,y,z表示有一条长度为z的边连接x和y(0<=z<=1,000,000,000)

Output

一个数表示答案

Input示例

6

1 2 1

1 3 1

1 4 1

3 5 1

4 6 1

Output示例

7

//配对方案为(1,2)(3,4)(5,6)

 

 

//考虑边的贡献,等于 min(a,b) (a,b是边连接的两个连通块的大小),可以容易想到,这样的情况必然可以构造成功,而且是答案的下界,或者,由树的重心,分开的部分,是可以构成的。

  1 # include <cstdio>
  2 # include <cstring>
  3 # include <iostream>
  4 # include <algorithm>
  5 using namespace std;
  6 # define LL long long
  7 # define INF 0x3f3f3f3f
  8 # define MX 100005
  9 /**************************/
 10 # define BUF_SIZE 100000
 11 # define OUT_SIZE 100000
 12 bool IOerror=0;
 13 
 14 inline char nc(){
 15     static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
 16     if (p1==pend){
 17         p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
 18         if (pend==p1){IOerror=1;return -1;}
 19         //{printf("IO error!\n");system("pause");for (;;);exit(0);}
 20     }
 21     return *p1++;
 22 }
 23 inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
 24 inline void read(int &x){
 25     bool sign=0; char ch=nc(); x=0;
 26     for (;blank(ch);ch=nc());
 27     if (IOerror)return;
 28     if (ch=='-')sign=1,ch=nc();
 29     for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
 30     if (sign)x=-x;
 31 }
 32 
 33 void print(LL x){
 34     static char s[25],*s1;s1=s;
 35     if (!x)*s1++='0';if (x<0)putchar('-'),x=-x;
 36     while(x)*s1++=x%10+'0',x/=10;
 37     while(s1--!=s)putchar(*s1);
 38 }
 39 
 40 struct Edge{
 41     int v,s;
 42     int nex;
 43 }edge[MX*2];
 44 
 45 int n,rm;
 46 int son[MX];
 47 int hlist[MX];
 48 int ansdex,mans;
 49 
 50 LL dis[MX];
 51 
 52 void addedge(int u,int v,int s)
 53 {
 54     edge[rm]=(Edge){v,s,hlist[u]};
 55     hlist[u]=rm++;
 56 }
 57 
 58 void dfs(int u,int pre)
 59 {
 60     int mmm=0;
 61     son[u]=1;
 62     for (int i=hlist[u];i!=-1;i=edge[i].nex)
 63     {
 64         int v = edge[i].v;
 65         if (v==pre) continue;
 66         dfs(v,u);
 67         son[u]+=son[v];
 68         mmm=max(mmm,son[v]);
 69     }
 70     mmm = max(mmm,n-son[u]);
 71     if (mmm<mans)
 72     {
 73         ansdex=u;
 74         mans = mmm;
 75     }
 76 }
 77 
 78 void dfs2(int x,int pre,LL s)
 79 {
 80     dis[x]=s;
 81     for(int i=hlist[x];i!=-1;i=edge[i].nex)
 82     {
 83         int v = edge[i].v;
 84         if (v==pre) continue;
 85         dfs2(v,x,s+edge[i].s);
 86     }
 87 }
 88 
 89 int main()
 90 {
 91     scanf("%d",&n);
 92     memset(hlist,-1,sizeof(hlist));
 93     rm=0; mans=INF;
 94     for (int i=1;i<n;i++)
 95     {
 96         int u,v,z;
 97         read(u),read(v),read(z);
 98         addedge(u,v,z);
 99         addedge(v,u,z);
100     }
101     dfs(1,-1);
102     dfs2(ansdex,-1,0);
103 
104     LL tot = 0;
105     for (int i=1;i<=n;i++)
106         tot+=dis[i];
107     print(tot);
108     return 0;
109 }
View Code

 

 

 

posted @ 2017-09-04 22:06  happy_codes  阅读(185)  评论(0编辑  收藏  举报