COJ262 HDNOIP201206施工方案
| HDNOIP201206施工方案 |
| 难度级别:A; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B |
|
试题描述
|
|
c国边防军在边境某处的阵地是由n个地堡组成的。工兵连受命来到阵地要进行两期施工。第一期的任务是挖掘暗道让所有地堡互联互通。 现已勘测设计了m条互不相交的暗道挖掘方案,如果这m条暗道都实施挖掘,肯定能达到互联互通的目的。 事实上,适当选择其中n-1个方案挖掘,就能实现互联互通,即从每个地堡出发都能到达其他任何一个地堡(允许经过别的地堡)。 连长精心谋算,在m个设计规划中选取了挖掘总距离最短且能保证互联互通的若干个暗道规划实施了挖掘, 完成了第一期的施工任务后又接受了第二期的施工任务,要求选择一个地堡进行扩建改造,使其能向每个地堡提供弹药。 为了让弹药供应更及时、更快捷,从改扩建的地堡到最远地堡的距离(称为最远输送距离)应当尽量小。 你的任务是先求出第一期施工挖掘的总距离,再求改扩建地堡最远输送距离的最小值。 |
|
输入
|
|
其中第一行是n和m,m>=n,下面的m行每行3个数xi、yi、zi,表示xi到yi的距离是zi,zi<1000000且m个距离互不相等
|
|
输出
|
|
两行各一个整数,第一行是第一期的挖掘总距离,第二行是最远输送距离的最小值。
|
|
输入示例
|
|
4 5
1 2 1 2 3 2 3 4 3 4 1 4 3 1 5 |
|
输出示例
|
|
6
3 |
|
其他说明
|
|
第一期挖掘1到2、2到3和3到4的3条暗道,第二期选择3号地堡进行改扩建,最远输送距离是3;60%的数据 n<10且m<20,80%的数据 n<1000且m<2000,100%的数据 n<100000且m<200000
|
第一问水水哒,直接MST即可。
第二问有两种做法:
做法一:可以猜想改建的地堡在直径上,因此两遍BFS即可
这个解法为什么是对的呢?我有一个绝妙的证明,但这里地方太小写不下。
#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(s,t) for(int i=s;i<=t;i++)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
inline int read() {
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
typedef long long LL;
const int maxn=;
const int maxm=;
struct Edge {
int u,v,w;
bool operator < (const Edge& ths) const {return w<ths.w;}
}e[maxm];
int n,m,pa[maxn];
int findset(int x) {return x==pa[x]?x:pa[x]=findset(pa[x]);}
LL ans1;
int first[maxn],to[maxn<<],next[maxn<<],dis[maxn<<],ToT;
void AddEdge(int u,int v,int w) {
to[++ToT]=v;dis[ToT]=w;next[ToT]=first[u];first[u]=ToT;
to[++ToT]=u;dis[ToT]=w;next[ToT]=first[v];first[v]=ToT;
}
int d[maxn],vis[maxn],p[maxn];
int bfs(int x) {
memset(vis,,sizeof(vis));
queue<int> Q;Q.push(x);vis[x]=;d[x]=;
while(!Q.empty()) {
x=Q.front();Q.pop();
ren if(!vis[to[i]]) vis[to[i]]=,Q.push(to[i]),d[to[i]]=d[x]+dis[i],p[to[i]]=x;
}
int ret=;
rep(,n) if(d[i]>d[ret]) ret=i;
return ret;
}
int main() {
n=read();m=read();
rep(,m) e[i].u=read(),e[i].v=read(),e[i].w=read();
rep(,n) pa[i]=i;
sort(e+,e+m+);
rep(,m) {
int x=findset(e[i].u),y=findset(e[i].v);
if(x!=y) pa[x]=y,AddEdge(e[i].u,e[i].v,e[i].w),ans1+=e[i].w;
}
printf("%lld\n",ans1);
int s=bfs(),t=bfs(s),x=t,ans2=1e9;
while(x!=s) {
ans2=min(ans2,max(d[t]-d[x],d[x]));
x=p[x];
}
printf("%d\n",ans2);
return ;
}
做法二:水水哒点分治就好啦。我们可以计算出每个点到其他点的最远距离,记为dp[i]。
当根节点为x时,我们可以更新所有子树的dp值与根节点的dp值,实现要正着反着各扫一遍。
#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(s,t) for(int i=s;i<=t;i++)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
inline int read() {
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
typedef long long LL;
const int maxn=;
const int maxm=;
struct Edge {
int u,v,w;
bool operator < (const Edge& ths) const {return w<ths.w;}
}e[maxm];
int n,m,pa[maxn];
int findset(int x) {return x==pa[x]?x:pa[x]=findset(pa[x]);}
LL ans1;
int first[maxn],to[maxn<<],next[maxn<<],dis[maxn<<],ToT;
void AddEdge(int u,int v,int w) {
to[++ToT]=v;dis[ToT]=w;next[ToT]=first[u];first[u]=ToT;
to[++ToT]=u;dis[ToT]=w;next[ToT]=first[v];first[v]=ToT;
}
int f[maxn],vis[maxn],dp[maxn],s[maxn],root,size;
void getroot(int x,int fa) {
s[x]=;int maxs=;
ren if(!vis[to[i]]&&to[i]!=fa) {
getroot(to[i],x);
s[x]+=s[to[i]];maxs=max(maxs,s[to[i]]);
}
f[x]=max(maxs,size-s[x]);
if(f[x]<f[root]) root=x;
}
int mxdep,dep2,A[maxn];
void dfs(int x,int fa,int dep) {
dp[x]=max(dp[x],mxdep+dep);dep2=max(dep,dep2);
ren if(!vis[to[i]]&&to[i]!=fa) dfs(to[i],x,dep+dis[i]);
}
void solve(int x) {
vis[x]=;mxdep=;int TAT=;
ren if(!vis[to[i]]) {
A[TAT++]=i;dep2=;
dfs(to[i],,dis[i]);
mxdep=max(mxdep,dep2);
}
dp[x]=max(dp[x],mxdep);mxdep=;
while(TAT--) {
dep2=;dfs(to[A[TAT]],,dis[A[TAT]]);
mxdep=max(mxdep,dep2);
}
ren if(!vis[to[i]]) {
f[]=size=s[to[i]];getroot(to[i],root=);
solve(root);
}
}
int main() {
n=read();m=read();
rep(,m) e[i].u=read(),e[i].v=read(),e[i].w=read();
rep(,n) pa[i]=i;
sort(e+,e+m+);
rep(,m) {
int x=findset(e[i].u),y=findset(e[i].v);
if(x!=y) pa[x]=y,AddEdge(e[i].u,e[i].v,e[i].w),ans1+=e[i].w;
}
printf("%lld\n",ans1);
f[]=size=n;getroot(,root=);
solve(root);
int ans2=1e9;
rep(,n) ans2=min(ans2,dp[i]);
printf("%d\n",ans2);
return ;
}
其实我认为第二个做法才是正解
COJ262 HDNOIP201206施工方案的更多相关文章
- HDNOIP201206施工方案
HDNOIP201206施工方案 难度级别:A: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 c国边防军在边境某处的阵地是由n个地堡组成的. ...
- codevs——1700 施工方案第二季
1700 施工方案第二季 2012年市队选拔赛北京 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description c国边防 ...
- codevs 1700 施工方案第二季
1700 施工方案第二季 2012年市队选拔赛北京 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description c国边防 ...
- CODEVS——T 1700 施工方案第二季
http://codevs.cn/problem/1700/ 2012年市队选拔赛北京 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 ...
- codevs1700 施工方案第二季
题目描述 Description c国边防军在边境某处的阵地是由n个地堡组成的.工兵连受命来到阵地要进行两期施工. 第一期的任务是挖掘暗道让所有地堡互联互通.现已勘测设计了m条互不相交的暗道挖掘方案, ...
- 浅谈自我对git的初步认识
本学期我们新增了一门课程,那就是软件工程,不知道为什么,感觉有种莫名的高大上.哈哈!难道是这个名称太抽象了吗?这个问题我感觉到后来肯定就明白了. 第一次博客,感觉好紧张哦,嘿嘿!老师让我们谈谈对git ...
- codevs与noi做题改错本目录
从2016.2.13开始: 1. 排序超时的问题---------目录:-测试习题 2. 超高精度乘法超时问题-----------目录:高精度计算 算法:快速傅里叶算法. 压位算法 3. 高精度 ...
- js 数据获取
http://www.cnhan.com/shantui/templates/MC500/TP001/js/template.js var qiaoContent="0";//0默 ...
- 杂项-建模:BIM
ylbtech-杂项-建模:BIM 建筑信息模型是建筑学.工程学及土木工程的新工具.建筑信息模型或建筑资讯模型一词由Autodesk所创的.它是来形容那些以三维图形为主.物件导向.建筑学有关的电脑辅助 ...
随机推荐
- ICMP-type对应表
一次在某个防火墙配置策略里看到如下的代码: iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT iptables -A FORWARD -p icmp ...
- 【leetcode】Best Time to Buy and Sell Stock III
Best Time to Buy and Sell Stock III Say you have an array for which the ith element is the price of ...
- static_cast dynamic_cast const_cast reinterpret_cast总结对比
[本文链接] http://www.cnblogs.com/hellogiser/p/static_cast-dynamic_cast-const_cast-reinterpret_cast.html ...
- iOS 一个工程中引用其他工程时要注意Skip Install选项
当主工程引用其他工程,以便使用他们生成的库的时候,在发布时,主要注意这个选项.这个选项的说明如下 Activating this setting when deployment locations a ...
- Heap:左式堆的应用例(任意序列变单调性最小价值)
首先来说一下什么是左式堆: A:左式堆是专门用来解优先队列合并的麻烦(任意二叉堆的合并都必须重新合并,O(N)的时间). 左式堆的性质: 1.定义零路经长:节点从没有两个两个儿子节点的路经长,把NUL ...
- myeclipse6.5中使用Alt+/不自动提示的修改
转载自:http://www.cnblogs.com/zhangnanblog/archive/2011/11/10/2244960.html 最近把MyEclipse8.5降到了MyEclipse6 ...
- 【USACO】checker
一看题目 经典的8皇后问题 不过是皇后数量可变而已 不用想 回溯法. 需要个生成每次可选择序列的函数, 在存储可选择的序列时按照先大后小的顺序排的.这样每次找最小和去掉最小都很方便,只要有个记录数量的 ...
- 说说localStorage
HTML5的本地存储是大势所趋,如果仅存储在内存中,则是sessionStorage,他们的语法都是一样,仅仅是一个存储在本地文件系统中,另一个存储在内存中(随着浏览器的关闭而消失),其语句如下: l ...
- 4.抽象工厂模式(Abstract Factory)
using System; using System.Reflection; namespace ConsoleApplication1 { class Program { static void M ...
- sdut 2165:Crack Mathmen(第二届山东省省赛原题,数论)
Crack Mathmen Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 Since mathmen take securit ...