http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3684
题目意思是:
给定一个n个节点的树,边有长度和权值。然后求一个最小值值Power,当把权值小于等于Power的边全部破坏时,所有的叶子节点都和中心点不连通。
题目保证树的中心唯一。
首先两次dfs求出树的直径,然后在这条路径上找到中点。
从任意点进行第一次dfs求得数的直径的一个端点,从这个端点dfs求得另一个端点
然后遍历直径,找到最接近直径一半的点就是中点。
然后以中点为根,进行树形DP(dfs)
对于一个点point来说,所需要的最小Power为,Min(Max(所有子节点所需要的Power),父节点的边的权值)
当然,根节点没有父节点,叶节点没有子节点,需要特判。
这么考虑,如果断开父节点和该节点,则该点的所有子节点也都断开连接,自然所有叶节点也断开连接。或者选择不断开,则所有的子节点的叶节点都必须断开。
最近刚刚开始写图论的题,代码还写得非常挫,以后完善了模板,会更新这里的代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define PB(x) push_back(x) 8 struct poi{ 9 int v,l,p; 10 void in(){ 11 scanf("%d%d",&l,&p); 12 } 13 }; 14 typedef vector<poi> dint; 15 dint s[10001]; 16 int n,l,d[10010],sum[10010]; 17 void dfs(int u,int f,int len){ 18 sum[u]=len; 19 for(int i=s[u].size()-1;i>=0;i--){ 20 poi v=s[u][i]; 21 if(v.v==f)continue; 22 dfs(v.v,u,len+v.l); 23 } 24 } 25 int gdfs(int u){ 26 dfs(u,-1,0); 27 int v=1; 28 for(int i=2;i<n;i++)if(sum[i]>sum[v])v=i; 29 return v; 30 } 31 bool dfs2(int u,int v,int f,int id){ 32 for(int i=s[u].size()-1;i>=0;i--){ 33 poi tmp=s[u][i]; 34 if(tmp.v==f)continue; 35 if(tmp.v==v || dfs2(tmp.v,v,u,id+1)){ 36 if(id+1>l)l=id+1; 37 d[id]=tmp.v; 38 return true; 39 } 40 } 41 return false; 42 } 43 void grod(int u,int v){ 44 l=1; 45 d[0]=u; 46 dfs2(u,v,-1,1); 47 } 48 inline int jl(int s,int t){return abs(s-(t<<1));} 49 50 int dfs3(int u,int f){ 51 int ans=-1; 52 int ans2; 53 for(int i=s[u].size()-1;i>=0;i--){ 54 poi tmp=s[u][i]; 55 if(tmp.v==f)ans2=tmp.p; 56 else ans=max(ans,dfs3(tmp.v,u)); 57 } 58 if(ans==-1)return ans2; 59 return min(ans,ans2); 60 } 61 62 int gans(int u){ 63 int ans=0; 64 for(int i=s[u].size()-1;i>=0;i--){ 65 poi v=s[u][i]; 66 ans=max(ans,dfs3(v.v,u)); 67 } 68 return ans; 69 } 70 int main() 71 { 72 while (~scanf("%d",&n)) 73 { 74 for(int i=1;i<=n;i++)s[i].clear(); 75 int u,v; 76 poi tmp; 77 for(int i=1;i<n;i++){ 78 scanf("%d%d",&u,&v); 79 tmp.in(); 80 tmp.v=u; 81 s[v].PB(tmp); 82 tmp.v=v; 83 s[u].PB(tmp); 84 } 85 u=gdfs(1); 86 v=gdfs(u); 87 grod(u,v); 88 int ans=0,sm=sum[v]; 89 for(int i=1;i<l;i++){ 90 if(jl(sm,sum[d[ans]])>jl(sm,sum[d[i]])) 91 ans=i; 92 } 93 ans=d[ans]; 94 printf("%d\n",gans(ans)); 95 } 96 return 0; 97 }