HDU 4679 Terrorist’s destroy (2013多校8 1004题 树形DP)

Terrorist’s destroy

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 24    Accepted Submission(s): 6


Problem Description
There is a city which is built like a tree.A terrorist wants to destroy the city's roads. But now he is alone, he can only destroy one road, then the city will be divided into two cities. Impression of the city is a number defined as the distance between the farthest two houses (As it relates to the fare).When the terrorist destroyed a road, he needs to spend some energy, assuming that the number is a.At the same time,he will get a number b which is maximum of the Impression of two cities. The terrorist wants to know which road to destroy so that the product of a and b will be minimized.You should find the road's id.
Note that the length of each road is one.
 

 

Input
The first line contains integer T(1<=T<=20), denote the number of the test cases.
For each test cases,the first line contains a integer n(1 < n <= 100000);denote the number of the houses;
Each of the following (n-1) lines contains third integers u,v,w, indicating there is a road between house u and houses v,and will cost terrorist w energy to destroy it.The id of these road is number from 1 to n-1.(1<=u<=n , 1<=v<=n , 1<=w<=10000)
 

 

Output
For each test case, output the case number first,and then output the id of the road which the terrorist should destroy.If the answer is not unique,output the smallest id.
 

 

Sample Input
2 5 4 5 1 1 5 1 2 1 1 3 5 1 5 1 4 1 1 3 1 5 1 1 2 5 1
 

 

Sample Output
Case #1: 2 Case #2: 3
 

 

Source
 

 

Recommend
zhuyuanchen520

 

 

 

各种dfs,导致爆栈了,加个栈挂,C++交果断AC了。

 

我是先求树的直径。

如果去掉的不是树的直径上的边,那么去掉后乘积就是w*直径长度

如果去掉直径上的边,那么直径两端各dfs一次就可以了

 

  1 /* ***********************************************
  2 Author        :kuangbin
  3 Created Time  :2013/8/15 14:48:54
  4 File Name     :F:\2013ACM练习\2013多校8\1004.cpp
  5 ************************************************ */
  6 #pragma comment(linker, "/STACK:1024000000,1024000000")
  7 
  8 #include <stdio.h>
  9 #include <string.h>
 10 #include <iostream>
 11 #include <algorithm>
 12 #include <vector>
 13 #include <queue>
 14 #include <set>
 15 #include <map>
 16 #include <string>
 17 #include <math.h>
 18 #include <stdlib.h>
 19 #include <time.h>
 20 using namespace std;
 21 
 22 const int MAXN = 100010;
 23 struct Edge
 24 {
 25     int to,next;
 26     int id;
 27     int w;
 28 }edge[MAXN*2];
 29 int mm[MAXN];
 30 int maxn[MAXN];
 31 int smaxn[MAXN];
 32 int head[MAXN],tot;
 33 void init()
 34 {
 35     memset(head,-1,sizeof(head));
 36     tot = 0;
 37 }
 38 void addedge(int u,int v,int w,int id)
 39 {
 40     edge[tot].to = v;
 41     edge[tot].w = w;
 42     edge[tot].id = id;
 43     edge[tot].next = head[u];
 44     head[u] = tot++;
 45     edge[tot].to = u;
 46     edge[tot].w = w;
 47     edge[tot].id = id;
 48     edge[tot].next = head[v];
 49     head[v] = tot++;
 50 }
 51 void dfs(int u,int pre)
 52 {
 53     mm[u] = 0;
 54     maxn[u] = 0;
 55     smaxn[u] = 0;
 56     for(int i = head[u];i != -1;i = edge[i].next)
 57     {
 58         int v = edge[i].to;
 59         if(v == pre)continue;
 60         dfs(v,u);
 61         if(maxn[v]+1 > smaxn[u])
 62         {
 63             smaxn[u] = maxn[v] + 1;
 64             if(smaxn[u] > maxn[u])
 65             {
 66                 swap(smaxn[u],maxn[u]);
 67             }
 68         }
 69         if(mm[v] > mm[u])
 70             mm[u] = mm[v];
 71     }
 72     mm[u] = max(mm[u],maxn[u]+smaxn[u]);
 73 }
 74 int ans;
 75 int dep[MAXN];
 76 int p[MAXN];
 77 bool used[MAXN];
 78 int cnt;
 79 int index;
 80 int a[MAXN];
 81 void solve(int u,int pre)
 82 {
 83     for(int i = head[u];i != -1;i = edge[i].next)
 84     {
 85         int v = edge[i].to;
 86         int w = edge[i].w;
 87         if(v == pre)continue;
 88         solve(v,u);
 89         if(used[v])
 90         {
 91             a[edge[i].id] = max(a[edge[i].id],w*mm[v]);
 92         }
 93         else
 94         {
 95             a[edge[i].id] = max(a[edge[i].id],w*cnt);
 96         }
 97     }
 98 }
 99 ;
100 void dfs1(int u,int pre)
101 {
102     p[u] = pre;
103     dep[u] = dep[pre] + 1;
104     for(int i = head[u]; i != -1;i = edge[i].next)
105     {
106         int v = edge[i].to;
107         if(v==pre)continue;
108         dfs1(v,u);
109     }
110 }
111 
112 int main()
113 {
114     //freopen("in.txt","r",stdin);
115     //freopen("out.txt","w",stdout);
116     int T;
117     int n;
118     scanf("%d",&T);
119     int u,v,w;
120     int iCase = 0;
121     while(T--)
122     {
123         iCase ++;
124         init();
125         scanf("%d",&n);
126         for(int i = 1;i < n;i++)
127         {
128             scanf("%d%d%d",&u,&v,&w);
129             addedge(u,v,w,i);
130         }
131         dep[0] = 0;
132         dfs1(1,0);
133         u = 1;
134         for(int i = 1;i <= n;i++)
135             if(dep[u] < dep[i])
136                 u = i;
137         dfs1(u,0);
138         v = 1;
139         for(int i =1;i <= n;i++)
140             if(dep[v] < dep[i])
141                 v = i;
142         cnt = dep[v]-1;
143         memset(used,false,sizeof(used));
144         int tmp = v;
145         while(tmp)
146         {
147             used[tmp] = true;
148             tmp = p[tmp];
149         }
150         for(int i = 1;i <= n;i++)
151             a[i] = 0;
152         ans = 1000000000;
153         dfs(u,0);
154         solve(u,-1);
155         dfs(v,0);
156         solve(v,-1);
157         for(int i = 1;i < n;i++)
158             if(a[i]<ans)
159             {
160                 ans = a[i];
161                 index = i;
162             }
163         printf("Case #%d: %d\n",iCase,index);
164     }
165     
166     return 0;
167 }

 

 

 

 

 

 

 

 

posted on 2013-08-15 17:09  kuangbin  阅读(1086)  评论(6编辑  收藏  举报

导航

JAVASCRIPT: