codevs1700 施工方案第二季

Posted gryzy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs1700 施工方案第二季相关的知识,希望对你有一定的参考价值。

题目描述 Description

c国边防军在边境某处的阵地是由n个地堡组成的。工兵连受命来到阵地要进行两期施工。

第一期的任务是挖掘暗道让所有地堡互联互通。现已勘测设计了m条互不相交的暗道挖掘方案,如果这m条暗道都实施挖掘,肯定能达到互联互通的目的。事实上,适当选择其中n-1个方案挖掘,就能实现互联互通,即从每个地堡出发都能到达其他任何一个地堡(允许经过别的地堡)。

连长精心谋算,在m个设计规划中选取了挖掘总距离最短且能保证互联互通的若干个暗道规划实施了挖掘,完成了第一期的施工任务后又接受了第二期的施工任务,要求选择一个地堡进行扩建改造,使其能向每个地堡提供弹药。为了让弹药供应更及时、更快捷,从改扩建的地堡到最远地堡的距离(称为最远输送距离)应当尽量小。

你的任务是先求出第一期施工挖掘的总距离,再求改扩建地堡最远输送距离的最小值。

输入描述 Input Description

其中第一行是n和m,m>=n
下面的m行每行3个数xi、yi、zi,表示xi到yi的距离是zi
  zi<1000000且m个距离互不相等

输出描述 Output Description

共包含两行,每行一个整数,
第一行是第一期的挖掘总距离,第二行是最远输送距离的最小值。

样例输入 Sample Input

4 5
1 2 1
2 3 2
3 4 3
4 1 4
3 1 5

样例输出 Sample Output

6
3

数据范围及提示 Data Size & Hint

【样例说明】
第一期挖掘1到2、2到3和3到4的3条暗道,第二期选择3号地堡进行改扩建,最远输送距离是3
【数据规模】
60%的数据 n<10且m<20
80%的数据 n<1000且m<2000
100%的数据 n<100000且m<200000

________________________________________________________________________________________________________________

树形动归

点i到大最远的点有两种可能,要么是它下面的叶子,也就是向西走,要么在父亲方向,也就是向上走。

向下的方向f[i]=max(f[j]+e[i->j].w)

向上的方向ff[i]=max(ff[fa[i]],f[son[fa[i](不是i点)])+e[i->fa[i]].w 

_________________________________________________________________________________________________________________

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=100005;
 4 const int maxm=200010;
 5 int n,m;
 6 struct edge
 7 {
 8     int u,v,w,nxt;
 9 }e[maxm<<1],ee[maxm];
10 int head[maxn],js;
11 void addage(int u,int v,int w)
12 {
13     e[++js].u=u;e[js].v=v;e[js].w=w;
14     e[js].nxt=head[u];head[u]=js;
15 }
16 int fa[maxn];
17 long long ans;
18 int find(int x)
19 {
20     if(fa[x]==x)return x;
21     return fa[x]=find(fa[x]);
22 }
23 bool un(int u,int v)
24 {
25     u=find(u),v=find(v);
26     if(u==v)return 0;
27     fa[v]=u;
28     return 1;
29 }
30 long long dl1[maxn],dl2[maxn],ul[maxn];
31 void dfs(int u,int fa)
32 {
33     for(int i=head[u];i;i=e[i].nxt)
34     {
35         int v=e[i].v;
36         if(v!=fa)
37         {
38             dfs(v,u);
39             if(dl1[v]+e[i].w>dl1[u])dl2[u]=dl1[u],dl1[u]=dl1[v]+e[i].w;
40             else if(dl1[v]+e[i].w>dl2[u])dl2[u]=dl1[v]+e[i].w;
41         }
42     }
43 }
44 void dfs2(int  u,int fa)
45 {
46     for(int i=head[u];i;i=e[i].nxt)
47     {
48         int v=e[i].v;
49         if(v!=fa)
50         {
51             if(dl1[v]+e[i].w==dl1[u])ul[v]=dl2[u];
52             else ul[v]=dl1[u];
53             if(ul[u]>ul[v])ul[v]=ul[u];
54             ul[v]+=e[i].w;
55             dfs2(v,u);
56         }
57     }
58 }
59 bool mycp(edge a,edge b)
60 {
61     return a.w<b.w;
62 }
63 int main()
64 {
65     scanf("%d%d",&n,&m);
66     for(int i=1;i<=n;++i)fa[i]=i;
67     for(int u,v,w,tp=0,i=0;i<m;++i)
68     {
69         scanf("%d%d%d",&u,&v,&w);
70         ee[i].u=u;ee[i].v=v;ee[i].w=w;
71         
72     }
73     sort(ee,ee+m,mycp);
74     for(int i=0;i<m;++i)
75     {
76         int u=ee[i].u,v=ee[i].v,w=ee[i].w;
77         if(un(u,v))
78         {
79             ans+=w;
80             addage(u,v,w);
81             addage(v,u,w);
82         }
83     }
84     dfs(1,0);
85     dfs2(1,0);
86     long long ans2=0x7ffffffffffffff;
87     for(int i=1;i<=n;++i)
88     {
89         int tp=max(ul[i],dl1[i]);
90         ans2=ans2<tp?ans2:tp;
91     }
92     printf("%lld
%lld",ans,ans2);
93     return 0;
94 }
View Code

 















以上是关于codevs1700 施工方案第二季的主要内容,如果未能解决你的问题,请参考以下文章

codevs1700 施工方案第二季

codevs——2693 上学路线(施工)

Codevs 2693 上学路线(施工)

S - 骨牌铺方格(第二季水)

场景联创 施耐德电气“绿色智能制造创赢计划”第二季收官

SpringCloud第二季之Nacos,Sentinel,Seata以及雪花算法学习笔记