HDU-4679-树的直径(树形dp)

Terrorist’s destroy

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


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
        给出一颗树,每条边具有一个权值wi,定义一颗树的得分是这颗树上距离最远的两个点的距离,边的长度都是1.现在请选择一条边拆除,使得这条边上的权值与拆掉边后形成的两颗子树中最大的得分的乘积达到最小,输出这条边。
    我们要知道每颗子树的直径,双dfs处理出 fm[u],sm[u],tm[u]记录以u为起点的前三大的路径和连接自那个连接点,然后枚举所有边,注意查找子树直径的时不可以通过这条边了。还是要注意前三大的直径必须来自于不同的临界点,否则可能出现非单链的情况。
    第一次处理时没有计算出直径,,结果竟然能AC...,数据好弱啊,,后来改了改依然能AC.
    
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<vector>
  5 using namespace std;
  6 #define inf 0x3f3f3f3f
  7 #pragma comment(linker, "/STACK:102400000,102400000")
  8 int first[100010],tot;
  9 int baba[100010];
 10 int fm[100010],sm[100010],tm[100010];
 11 int fid[100010],sid[100010],tid[100010];
 12 struct Edge
 13 {
 14     int u,v,w,next;
 15 }e[201000];
 16 void add(int u,int v,int w){
 17     e[tot].u=u;
 18     e[tot].v=v;
 19     e[tot].w=w;
 20     e[tot].next=first[u];
 21     first[u]=tot++;
 22 }
 23 void dfs1(int u,int fa)
 24 {
 25     fm[u]=sm[u]=tm[u]=0;
 26     fid[u]=sid[u]=tid[u]=0;
 27     baba[u]=fa;
 28     for(int i=first[u];i+1;i=e[i].next){
 29         int v=e[i].v;
 30         if(v==fa) continue;
 31         dfs1(v,u);
 32         if(fm[v]+1>tm[u]&&v!=fid[u]&&v!=sid[u]){
 33             tm[u]=fm[v]+1;
 34             tid[u]=v;
 35             if(tm[u]>sm[u]){
 36                 swap(tm[u],sm[u]);
 37                 swap(tid[u],sid[u]);
 38             }
 39             if(sm[u]>fm[u]){
 40                 swap(sm[u],fm[u]);
 41                 swap(sid[u],fid[u]);
 42             }
 43         }
 44         if(sm[v]+1>tm[u]&&v!=fid[u]&&v!=sid[u]){
 45             tm[u]=sm[v]+1;
 46             tid[u]=v;
 47             if(tm[u]>sm[u]){
 48                 swap(tm[u],sm[u]);
 49                 swap(tid[u],sid[u]);
 50             }
 51             if(sm[u]>fm[u]){
 52                 swap(sm[u],fm[u]);
 53                 swap(sid[u],fid[u]);
 54             }
 55         }
 56         if(tm[v]+1>tm[u]&&v!=fid[u]&&v!=sid[u]){
 57             tm[u]=tm[v]+1;
 58             tid[u]=v;
 59             if(tm[u]>sm[u]){
 60                 swap(tm[u],sm[u]);
 61                 swap(tid[u],sid[u]);
 62             }
 63             if(sm[u]>fm[u]){
 64                 swap(sm[u],fm[u]);
 65                 swap(sid[u],fid[u]);
 66             }
 67         }
 68     }
 69 }
 70 void dfs2(int u,int fa)
 71 {
 72     if(fid[fa]!=u&&fid[u]!=fa&&sid[u]!=fa&&fm[fa]+1>tm[u]){
 73         tm[u]=fm[fa]+1;
 74         tid[u]=fa;
 75         if(tm[u]>sm[u]){
 76                 swap(tm[u],sm[u]);
 77                 swap(tid[u],sid[u]);
 78             }
 79         if(sm[u]>fm[u]){
 80                 swap(sm[u],fm[u]);
 81                 swap(sid[u],fid[u]);
 82             }
 83     }
 84     if(sid[fa]!=u&&fid[u]!=fa&&sid[u]!=fa&&sm[fa]+1>tm[u]){
 85         tm[u]=sm[fa]+1;
 86         tid[u]=fa;
 87         if(tm[u]>sm[u]){
 88                 swap(tm[u],sm[u]);
 89                 swap(tid[u],sid[u]);
 90             }
 91             if(sm[u]>fm[u]){
 92                 swap(sm[u],fm[u]);
 93                 swap(sid[u],fid[u]);
 94             }
 95     }
 96     if(tid[fa]!=u&&fid[u]!=fa&&sid[u]!=fa&&tm[fa]+1>tm[u]){
 97         tm[u]=tm[fa]+1;
 98         tid[u]=fa;
 99         if(tm[u]>sm[u]){
100                 swap(tm[u],sm[u]);
101                 swap(tid[u],sid[u]);
102             }
103             if(sm[u]>fm[u]){
104                 swap(sm[u],fm[u]);
105                 swap(sid[u],fid[u]);
106             }
107     }
108     for(int i=first[u];~i;i=e[i].next){
109         int v=e[i].v;
110         if(v==fa) continue;
111         dfs2(v,u);
112     }
113 }
114 int main()
115 {
116     int n,i,j,k,u,v,w;
117     int t,cas=0;
118     cin>>t;
119     while(t--){
120         memset(first,-1,sizeof(first));
121         tot=0;
122         scanf("%d",&n);
123         for(i=1;i<n;++i){
124             scanf("%d%d%d",&u,&v,&w);
125             add(u,v,w);
126             add(v,u,w);
127         }
128         dfs1(1,0);
129         dfs2(1,0);
130         /*for(i=1;i<=n;++i)
131             cout<<fm[i]<<' '<<sm[i]<<' '<<tm[i]<<endl;*/
132         int ans=inf,id=0;
133         for(i=0;i<tot;i+=2){
134             u=e[i].u,v=e[i].v,w=e[i].w;
135             int t1=0,t2=0;
136         if(baba[v]==u){
137         t1=0,t2=0;
138             if(fid[u]!=v&&sid[u]!=v){
139                 t1=max(t1,fm[u]+sm[u]);
140             }
141             else if(sid[u]!=v&&tid[u]!=v){
142                 t1=max(t1,sm[u]+tm[u]);
143             }
144             else t1=max(t1,fm[u]+tm[u]);
145 
146             if(fid[v]!=u&&sid[v]!=u){
147                 t2=max(t2,fm[v]+sm[v]);
148             }
149             else if(sid[v]!=u&&tid[v]!=u){
150                 t2=max(t2,sm[v]+tm[v]);
151             }
152             else t2=max(t2,fm[v]+tm[v]);
153 
154 
155         }
156         else{
157             if(fid[u]!=v&&sid[u]!=v){
158                 t2=max(t2,fm[u]+sm[u]);
159             }
160             else if(sid[u]!=v&&tid[u]!=v){
161                 t2=max(t2,sm[u]+tm[u]);
162             }
163             else t2=max(t2,fm[u]+tm[u]);
164 
165             if(fid[v]!=u&&sid[v]!=u){
166                 t1=max(t1,fm[v]+sm[v]);
167             }
168             else if(sid[v]!=u&&tid[v]!=u){
169                 t1=max(t1,sm[v]+tm[v]);
170             }
171             else t1=max(t1,fm[v]+tm[v]);
172         }
173             if(w*max(t1,t2)<ans){
174                 ans=w*max(t1,t2);
175                 id=i;
176             }
177         }
178         printf("Case #%d: %d\n",++cas,(id+2)/2);
179     }
180     return 0;
181 }

猜你喜欢

转载自www.cnblogs.com/zzqc/p/8874160.html