http://codevs.cn/problem/1700/

2012年市队选拔赛北京

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 黄金 Gold
 查看运行结果
 
 
题目描述 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

第一问:最小生成树可求

第二问:树上距离最远的两点的路径为直径,显然将城堡在直径上的点扩建最优

    (记录从直径某一段点,到直径上每点的距离,则ans=min(ans,val[t]-val[u])

 #include <algorithm>
#include <cstring>
#include <cstdio> #define LL long long
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
inline void read(int &x)
{
x=; register char ch=getchar();
for(; ch>''||ch<''; ) ch=getchar();
for(; ch>=''&&ch<=''; ch=getchar()) x=x*+ch-'';
}
const int N(+);
const int M(+);
int n,m,head[N],sumedge;
struct Edge {
int v,next,w;
Edge(int v=,int next=,int w=):v(v),next(next),w(w){}
}edge[N<<];
struct Road {
int u,v,w;
bool operator < (const Road x)const
{
return w<x.w;
}
Road(int u=,int v=,int w=):u(u),v(v),w(w){}
}road[M];
inline void ins(int u,int v,int w)
{
edge[++sumedge]=Edge(v,head[u],w);
head[u]=sumedge;
} int fa[N];
int find(int x)
{
return x==fa[x]?x:fa[x]=find(fa[x]);
}
inline LL K_for_get_road()
{
int cnt=;
LL ret=;
std::sort(road+,road+m+);
for(int i=; i<=n; ++i) fa[i]=i;
for(int fx,fy,i=; i<=m; ++i)
{
fx=find(road[i].u),fy=find(road[i].v);
if(fx==fy) continue;
fa[fx]=fy; ret+=(LL)road[i].w;
ins(road[i].u,road[i].v,road[i].w);
ins(road[i].v,road[i].u,road[i].w);
if(++cnt==n-) return ret;
}
return ret;
} LL val[N],ans;
int s,t,pre[N];
void DFS(int u)
{
for(int x,v,i=head[u]; i; i=edge[i].next)
{
v=edge[i].v;
if(v==pre[u]) continue;
val[v]=val[u]+(LL)edge[i].w;
pre[v]=u; DFS(v);
}
}
void Get(int u)
{
if(pre[u]) Get(pre[u]);
ans=min(ans,max(val[u],val[t]-val[u]));
} int Presist()
{
read(n),read(m);
for(int u,v,w,i=; i<=m; ++i)
read(u),read(v),read(w),road[i]=Road(u,v,w);
printf("%lld\n",K_for_get_road()); DFS(s=);
for(int i=; i<=n; ++i) if(val[i]>val[s]) s=i;
memset(val,,sizeof(val));
memset(pre,,sizeof(pre));
DFS(s);t=;
for(int i=; i<=n; ++i) if(val[i]>val[t]) t=i;
ans=val[t]; Get(t);
printf("%lld\n",ans);
return ;
} int Aptal=Presist();
int main(){;}

最新文章

  1. 微信小程序demo理解
  2. 洛谷P3406 海底高铁[差分 贪心]
  3. [转]简单理解Socket
  4. Android使用SQLite数据库(3)
  5. NEC学习 ---- 布局 -两列定宽
  6. mysql and 和 or 的 优先级和 查询问题
  7. Codeforces Round #327 (Div. 2)-Wizards&#39; Duel
  8. Java基础——左移和右移
  9. ajax 乱码
  10. Android屏幕适应详解(一)
  11. Slony-I的限制
  12. 【LeetCode 209】Minimum Size Subarray Sum
  13. selenium python 环境搭建
  14. XML实例文档
  15. 黄聪:Microsoft Enterprise Library 5.0 系列教程(三) Validation Application Block (高级)
  16. 2016-2017 ACM-ICPC, Egyptian Collegiate Programming Contest (ECPC 16) 题解
  17. 全面盘点当前Android后台保活方案的真实运行效果(截止2019年前)
  18. 无备份时用dbms_repair恢复坏块的方法
  19. 南方IT学校期末PCB结课项目考试(实操)说明书
  20. MySQL中kill掉所有表的进程

热门文章

  1. Spring MVC过滤器-HiddenHttpMethodFilter
  2. 390 Elimination Game 淘汰游戏
  3. 十年后我不会log,还是活的很好啊
  4. es6常用的语法
  5. getBlockTable delete pline
  6. xmpp 消息和好友上下线(3)
  7. extjs动态插入一列
  8. 08css、JS
  9. [Algorithm] 5. Kth Largest Element
  10. PKI相关知识简述