1737 配对
给出一棵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 }