混沌DM

DM Hunter

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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 }

 

 

posted on 2013-01-21 19:12  混沌DM  阅读(622)  评论(0编辑  收藏  举报