习题:codevs 1519 过路费 解题报告
今天拿了这道题目练练手,感觉自己代码能力又增强了不少;
我的思路跟别人可能不一样。
首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这个kruskal选边建图的过程。
struct kruskalsolve{
int l,r,w;
}kr[maxm];
此处省略的内容接下来会有给出全部代码
int find(int x){
if(f[x] != x)f[x] = find(f[x]);
return f[x];
}
void kruskal_check(int m){
int cnte = ;
sort(kr+,kr+m+,cmp);
for(int i = ;i <= n;++i){
f[i] = i;
}
for(int i = ;i <= m;++i){
if(cnte == n-)break;
int s = find(kr[i].l);
int t = find(kr[i].r);
if(s != t){
f[s] = t;
e[++cnte][] = kr[i].l;
e[cnte][] = kr[i].r;
e[cnte][] = kr[i].w;
addedge(kr[i].l,kr[i].r);
addedge(kr[i].r,kr[i].l);
}
}
}
做到这里,有人可能觉得接下来一个LCA接着就可以AC了,不过蒟蒻认为这样做效率有点低,然后代码也不怎么好写,于是换成了树链剖分+线段树模板维护查询区间最大值的思路。(什么思路!!明明是套板子……这要解释的话就比较尴尬了)
这样的话效率就是O(nlogn)的总效率,感觉不错,但是就是代码量稍微有点大,请读者见谅。
建议大家还是先去学一下树链剖分的思路和板子,然后在看我的题解,毕竟光copy别人的,自己时间长了肯定忘,最好的还是自己懂了思路然后再自己手码出来。
废话不说了,上代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = ,maxm = ;
int n,m,q,s,t;
int id[maxn],top[maxn],son[maxn],fa[maxn],h[maxn],cnt,siz[maxn],dep[maxn],val[maxn],num,f[maxn];
struct kruskalsolve{
int l,r,w;
}kr[maxm];
struct edge{
int fr,to,next;
}edges[maxn<<];
struct segtree{
int l,r,val;
}tr[maxm<<];
int e[maxn][];
bool cmp(kruskalsolve a,kruskalsolve b){
return a.w < b.w;
}
void init(){
cnt = ;
memset(h,-,sizeof(h));
memset(dep,,sizeof(dep));
memset(siz,,sizeof(siz));
memset(fa,,sizeof(fa));
memset(id,,sizeof(id));
memset(edges,,sizeof(edge));
memset(val,,sizeof(val));
memset(e,,sizeof(e));
memset(top,,sizeof(top));
memset(tr,,sizeof(tr));
num = ;
}
void addedge(int u,int v){
edges[cnt].fr = u;edges[cnt].to = v;edges[cnt].next = h[u];
h[u] = cnt++;
}
int find(int x){
if(f[x] != x)f[x] = find(f[x]);
return f[x];
}
void kruskal_check(int m){
int cnte = ;
sort(kr+,kr+m+,cmp);
for(int i = ;i <= n;++i){
f[i] = i;
}
for(int i = ;i <= m;++i){
if(cnte == n-)break;
int s = find(kr[i].l);
int t = find(kr[i].r);
if(s != t){
f[s] = t;
e[++cnte][] = kr[i].l;
e[cnte][] = kr[i].r;
e[cnte][] = kr[i].w;
addedge(kr[i].l,kr[i].r);
addedge(kr[i].r,kr[i].l);
}
}
}
void dfs1(int now ,int father ,int d){
dep[now] = d;
fa[now] = father;
son[now] = ;
siz[now] = ;
for(int i = h[now];i != -;i = edges[i].next){
edge e1 = edges[i];
if(e1.to == father)continue;
dfs1(e1.to,now,d+);
siz[now] += siz[e1.to];
if(siz[son[now]] < siz[e1.to])son[now] = e1.to;
}
}
void getpos(int now,int tp){
id[now] = ++num;
top[now] = tp;
if(son[now])getpos(son[now],tp);
for(int i = h[now];i != -;i = edges[i].next){
edge e1 = edges[i];
if(e1.to == son[now] || e1.to == fa[now])continue;
getpos(e1.to,e1.to);
}
}
void push_up(int v){
tr[v].val = max(tr[v<<].val,tr[v<<|].val);
}
void build(int l,int r,int now){
tr[now].l = l;
tr[now].r = r;
if(l == r){
tr[now].val = val[l];
return;
}
int mid = (l + r) >> ;
build(l,mid,now<<);
build(mid+,r,now<<|);
push_up(now);
}
int query(int x,int l,int r){
if(l <= tr[x].l && r >= tr[x].r){
return tr[x].val;
}
int ans = ;
int mid = (tr[x].l + tr[x].r) >> ;
if(l <= mid)ans = max(ans,query(x<<,l,r));
if(r > mid)ans = max(ans,query(x<<|,l,r));
return ans;
}
int youth(int u,int v){
int ans = ;
while(top[u] != top[v]){
if(dep[top[u]] < dep[top[v]])swap(u,v);
ans = max(ans,query(,id[top[u]],id[u]));
u = fa[top[u]];
}
if(u == v)return ans;
if(dep[u] > dep[v])swap(u,v);
ans = max(ans,query(,id[son[u]],id[v]));
return ans;
}
int main(){
init();
scanf("%d%d",&n,&m);
for(int i = ;i <= m;++i){
scanf("%d%d%d",&kr[i].l,&kr[i].r,&kr[i].w);
}
kruskal_check(m);
dfs1(,-,);
getpos(,);
for(int i = ;i < n;++i){
if(dep[e[i][]] < dep[e[i][]])swap(e[i][],e[i][]);
val[id[e[i][]]] = e[i][];
}
build(,n,);
scanf("%d",&q);
for(int i = ;i <= q;++i){
scanf("%d%d",&s,&t);
printf("%d\n",youth(s,t));
}
return ;
}
这次写的解题报告就到这里吧,以后会尽量去写。
习题:codevs 1519 过路费 解题报告的更多相关文章
- codevs 1519 过路费 最小生成树+倍增
/*codevs 1519 过路费 最小生成树+倍增*/ #include<iostream> #include<cstdio> #include<cstring> ...
- Codevs 1519 过路费(Mst+Lca)
1519 过路费 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 大师 Master 题目描述 Description 在某个遥远的国家里,有 n个城市.编号为 1,2,3,-,n. ...
- [Codevs1519]过路费解题报告|最小生成树|LCA
在某个遥远的国家里,有 n个城市.编号为 1,2,3,…,n.这个国家的政府修建了m 条双向道路,每条道路连接着两个城市.政府规定从城市 S 到城市T需要收取的过路费为所经过城市之间道路长度的最大值. ...
- codevs 1519 过路费
时间限制: 1 s 空间限制: 256000 KB 题目等级 : 大师 Master 题目描述 Description 在某个遥远的国家里,有 n个城市.编号为 1,2,3,…,n.这个国家的政府 ...
- 习题:codevs 2822 爱在心中 解题报告
这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...
- 习题:codevs 1035 火车停留解题报告
本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...
- 习题: codevs 2492 上帝造题的七分钟2 解题报告
这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...
- [置顶] 刘汝佳《训练指南》动态规划::Beginner (25题)解题报告汇总
本文出自 http://blog.csdn.net/shuangde800 刘汝佳<算法竞赛入门经典-训练指南>的动态规划部分的习题Beginner 打开 这个专题一共有25题,刷完 ...
- CH Round #56 - 国庆节欢乐赛解题报告
最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...
随机推荐
- 如何在 ETL 项目中统一管理上百个 SSIS 包的日志和包配置框架
一直准备写这么一篇有关 SSIS 日志系统的文章,但是发现很难一次写的很完整.因为这篇文章的内容可扩展的性太强,每多扩展一部分就意味着需要更多代码,示例和理论支撑.因此,我选择我觉得比较通用的 LOG ...
- LLBL Gen + Entity Framework 程序设计入门
Entity Framework推出有好几年,除了微软的Visual Studio可以做实体框架开发外,第三方的开发工具如LLBL Gen, Devart Entity Developer也可以用来做 ...
- 最简单的SVN环境搭建过程
本文简单描述最简单的SVN环境搭建过程 搭建环境:windows (个人验证了windows2003,windows xp) 使用软件:Setup-Subversion-1.6.17 //Serve ...
- 在IIS中部署ASP.NET 5应用程序遭遇的问题
用VS2015中创建了一个非常简单的ASP.NET5程序: 在Startup.cs中只输入一行代码: using System; using Microsoft.AspNet.Builder; usi ...
- [java] 汇率换算器实现-插曲1-正则表达式(1)
[java] 汇率换算器实现-插曲1-正则表达式(1) // */ // ]]> // */ // ]]> [java] 汇率换算器实现-插曲1-正则表达式(1) Table of C ...
- JavaScript和DOM的产生与发展
首先本篇文章摘自:http://itbilu.com/javascript/js/Vyxodm_1g.html 非常感谢本篇文章的作者,他理清了我映像中混乱的DOM Level级别.让我知道了DOM0 ...
- Android客户端消息推送原理简介
首先简单介绍一下Android消息推送的主要三种方式,如果你已经看过类似的文章,请直接忽略三种介绍. 1.使用SMS服务,即服务器端发送短信,然后手机客户端监听短信的广播,然后对数据进行一定的处 ...
- ASP.NET MVC 使用Jquery Uploadify 在非IE浏览器下Http Error的解决方案
解决Uploadify上传控件在非IE浏览器中不工作,需要做如下2步修改: 1.Global.asax文件中,实现Application_BeginRequest函数: void Applicatio ...
- 使用NuGet打包并发布至ProGet过程 (打包再次详解)【下篇】
一.前言 上篇[1]主要介绍了利用csproj文件使用NuGet打包至ProGet的过程,并附上了用于在Jenkins上运行的python脚本.本篇的主要内容分为以下几点: 1. Nuspec与Nup ...
- 基于MVC4+EasyUI的Web开发框架经验总结(11)--使用Bundles处理简化页面代码
在Web开发的时候,我们很多时候,需要引用很多CSS文件.JS文件,随着使用更多的插件或者独立样式文件,可能我们的Web界面代码会越来越臃肿,看起来也很累赘,在MVC里面提供了一个Bundle的对象, ...