习题: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的矩阵,矩阵中的每个位置上都长着一棵树 ...
随机推荐
- 使用(POI)SAX处理Excel文件,防止内存溢出
POISAXReader h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-chi ...
- Jenkins+MSbuild+SVN实现dotnet持续集成 快速搭建持续集成环境
Jenkins是一个可扩展的持续集成引擎,Jenkins非常易于安装和配置,简单易用,下面开始搭建dotnet持续集成环境 一.准备工作 1.系统管理-->管理插件-->可选插件中找到MS ...
- git回滚到任意版本
git回滚到任意版本 先显示提交的log $ git log -3 commit 4dc08bb8996a6ee02f Author: Mark <xxx@xx.com> Date: We ...
- 静态(static)代码块、构造代码块、构造函数、父类子类执行顺序
静态代码块:static修饰的代码块. 在类加载-初始化的时候进行,主要目的是给变量赋予初始值 构造代码块:直接在类中定义且没有加static关键字的代码块称为构造代码块. java会把构造代码块放到 ...
- DataGrid--多记录CRUD
最近在做一个datagrid,但因为引用的Jquery,加上初学者,所以难免费尽周折.现在将完整版贴出来,跟大家分享,一起切磋,也方便自己回顾学习. ps:第一次发帖,不知排版效果如何,瑕疵勿怪. 首 ...
- RobotFramework - 在Window7系统中安装本地RobotFrmamework自动化测试环境
RIDE Installation 安装顺序:Python ---> setuptools & pip ---> Robot Framewok ---> wxPython(v ...
- [linux] is not in the sudoers file
$su - $visudo append usrname ALL=(ALL) ALL save done ctrl+d
- web前端学习笔记(CSS盒子的定位)
相对定位 使用相对定位的盒子的位置常以标准流的排版方式为基础,然后使盒子相对于它在原本的标准位置偏移指定的距离.相对定位的盒子仍在标准流中,它后面的盒子仍以标准流方式对待它. 使用relat ...
- 实用js代码大全
实用js代码大全 //过滤数字 <input type=text onkeypress="return event.keyCode>=48&&event.keyC ...
- AndroidManifest.xml配置文件
AndroidManifest.xml启动文件 主activity: <activity android:name="com.example.android01.MainActivit ...