zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    数据库 concat 与 ||
    mysql时间戳详解及运用
    mysql数据库事务的操作与理解
    数据分析实战——03丨Python基础语法:开始你的Python之旅
    数据分析实战——02丨学习数据挖掘的最佳路径是什么?
    数据分析实战——01丨数据分析全景图及修炼指南
    数据分析实战——开篇词 | 你为什么需要数据分析能力?
    从0开始学大数据学习笔记——37.如何对数据进行分类和预测?
    坚毅(GRIT)阅读笔记
    Make over monday – 每周动手实践的Tableau社区网站
  • 原文地址:https://www.cnblogs.com/hundundm/p/2870271.html
Copyright © 2011-2022 走看看