zoukankan      html  css  js  c++  java
  • bzoj 3246 [Ioi2013]Dreaming 贪心

    [Ioi2013]Dreaming

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 638  Solved: 241
    [Submit][Status][Discuss]

    Description

    Serpent(水蛇)生活的地方有N个水坑,编号为0,...,N - 1,有M条双向小路连接这些水坑。每两个水坑之间至多有一条路径(路径包含一条或多条小路)相互连接,有些水坑之间根本无法互通(即M ≤ N-1 )。Serpent走过每条小路需要一个固定的天数,不同的小路需要的天数可能不同。Serpent的朋友袋鼠希望新修 N - M - 1条小路,让Serpent可以在任何两个水坑间游走。袋鼠可以在任意两个水坑之间修路,Serpent通过每条新路的时间都是L天。袋鼠希望找到一种修路方式使得修路之后Serpent在每两个水坑之间游走的最长时间最短。

    举例说明

    上图中有12个水坑8条小路( N = 12, M = 8)。假如L = 2 ,即Serpent通过任何一条新路都需要2天。那么,袋鼠可以修建3条新路: 
    水坑1和水坑2之间;
    水坑1和水坑6之间;
    水坑4和水坑10之间。

    上图显示了修路后的最终状态。从水坑0走到水坑11的时间最长,需要18天。这是 最佳结果,无论袋鼠如何选择修路方式,总会存在一些水坑对,Serpent需要18天 或者更长时间从其中一个走到另一个。
     

    Input

    N : 水坑的数目。
    M : 原本存在的小路的数目。
    L : Serpent通过新修的路经的时间。
    A, B 和 T: 三个包含M个元素的数组,分别表示每条小路的两个端点和通过这条小路的时间。例如,第i条小路连接水坑 A[i-1]和水坑B[i-1],通过这条小路的时间是T[i-1]天。
     
     

    Output


    如上所述,表示游走于两个距离最远的水坑之间所需的时间。

    Sample Input

    12 8 2
    0 8 4
    8 2 2
    2 7 4
    5 11 3
    5 1 7
    1 3 1
    1 9 5
    10 6 3

    Sample Output

    18

    HINT

     n <= 500000

     

    题目大意

    给定n个点m条边的森林,每条边有边权。要求用长度为L的边把它连成一棵树,且直径最小。

    n≤500000

    分析

    首先对于森林中每一棵树,它只有一条路径可能会对答案有贡献。为了使答案尽量小,那就要使这个值尽量小。那么可以选择它的所有点中,到达其它点距离最大值最小的,去和其它树连接。然后这个点对答案的贡献就是这个距离。

    那么会发现,这些数看成一个点之后,又会连成一棵树。 
    由于这棵树的形态是任意的,肯定是选择一个点作为根,然后其它点和根直接连接最优。为了答案尽量小,又一定是把上面所述距离的最大值作为根。

    那么对答案有贡献的就只有三种情况: 
    1. 原来每棵树的直径 
    2. 距离最大值+距离次大值+L 
    3. 距离次大值+距离第3大值+2L

     1 #include<cstring>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cmath>
     6 #include<queue>
     7 #include<map>
     8 
     9 #define N 500007
    10 #define M 1000007
    11 using namespace std;
    12 inline int read()
    13 {
    14     int x=0,f=1;char ch=getchar();
    15     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    16     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    17     return x*f;
    18 }
    19 
    20 int n,m,L;
    21 int tot,h[N],e[M],nxt[M],w[M],fa[N],dis[N],D[N],ans,cnt,len[N];
    22 bool v[N];
    23 char c;
    24 
    25 void add(int x,int y,int d)
    26 {
    27     e[++tot]=y; nxt[tot]=h[x]; w[tot]=d; h[x]=tot;
    28 }
    29 
    30 int main()
    31 {
    32     n=read(); m=read(); L=read();
    33     while (m--)
    34     {
    35         int x=read()+1,y=read()+1,w=read();
    36         add(x,y,w); add(y,x,w);
    37     }
    38     for (int i=1;i<=n;i++) 
    39         if (!v[i])
    40            {    
    41             D[tot=1]=i;
    42                for (int j=1;j<=tot;j++)
    43             {
    44                 int x=D[j];
    45                 v[x]=1;
    46                 for (int k=h[x];k;k=nxt[k]) 
    47                     if (e[k]!=fa[x]) D[++tot]=e[k],dis[e[k]]=dis[x]+w[k],fa[e[k]]=x;
    48             }
    49             int r=D[tot];
    50             for (int j=1;j<tot;j++) 
    51                 if (dis[D[j]]>dis[r]) r=D[j];
    52             D[tot=1]=r; dis[r]=0; fa[r]=0;
    53             for (int j=1;j<=tot;j++)
    54             {
    55                 int x=D[j];
    56                 for (int k=h[x];k;k=nxt[k])
    57                     if (e[k]!=fa[x])
    58                     {
    59                         D[++tot]=e[k]; 
    60                         dis[e[k]]=dis[x]+w[k]; 
    61                         fa[e[k]]=x;
    62                     }
    63             }
    64             r=D[tot];
    65             for (int j=1;j<tot;j++)
    66                 if (dis[D[j]]>dis[r]) r=D[j];
    67             ans=max(ans,dis[r]); len[++cnt]=dis[r];
    68             for (int j=r;j>0;j=fa[j]) len[cnt]=min(len[cnt],max(dis[j],dis[r]-dis[j]));
    69            }
    70     sort(len+1,len+cnt+1);
    71     if (cnt==2) ans=max(ans,len[2]+len[1]+L);
    72     else if (cnt>2) ans=max(ans,max(len[cnt]+len[cnt-1]+L,len[cnt-1]+len[cnt-2]+L*2));
    73     printf("%d
    ",ans);
    74 }
  • 相关阅读:
    非常实用的php各种文件操作函数
    两个自用的Dota2 自走棋辅助工具:阵容模拟器与UI Mod插件
    Scratch 数字游戏
    初识Scratch 3.0
    何时重头来
    cocos2d-x 3.0 Armature jsb 初体验
    cocosbuilder中的Callbacks和sound effects
    cocos2dx js文件加密为jsc文件
    cocos2dx jsb 在IOS与安卓下的一些不同之处
    安卓打包记录
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8847823.html
Copyright © 2011-2022 走看看