ZOJ 3684 ZJU2013年01月月赛I题 Destroy

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 }

 

 

你可能感兴趣的:(des)