zoukankan      html  css  js  c++  java
  • 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多校81004.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
    ",iCase,index);
    164     }
    165     
    166     return 0;
    167 }
  • 相关阅读:
    node项目发布pm2
    图片地址获取图片信息
    前端文件上传 获取文件大小 获取图片宽高
    前端上传图片预览
    vue按钮防暴力点击
    小程序父子组件之间的通信
    form表单
    es6-函数的扩展
    php的魔术常量以及类的模式方法
    OpenStack笔记
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3260088.html
Copyright © 2011-2022 走看看