今天拿了这道题目练练手,感觉自己代码能力又增强了不少;

我的思路跟别人可能不一样。

首先我们很容易就能看出,我们需要的边就是最小生成树算法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 过路费 解题报告的更多相关文章

  1. codevs 1519 过路费 最小生成树+倍增

    /*codevs 1519 过路费 最小生成树+倍增*/ #include<iostream> #include<cstdio> #include<cstring> ...

  2. Codevs 1519 过路费(Mst+Lca)

    1519 过路费 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 大师 Master 题目描述 Description 在某个遥远的国家里,有 n个城市.编号为 1,2,3,-,n. ...

  3. [Codevs1519]过路费解题报告|最小生成树|LCA

    在某个遥远的国家里,有 n个城市.编号为 1,2,3,…,n.这个国家的政府修建了m 条双向道路,每条道路连接着两个城市.政府规定从城市 S 到城市T需要收取的过路费为所经过城市之间道路长度的最大值. ...

  4. codevs 1519 过路费

    时间限制: 1 s  空间限制: 256000 KB  题目等级 : 大师 Master 题目描述 Description 在某个遥远的国家里,有 n个城市.编号为 1,2,3,…,n.这个国家的政府 ...

  5. 习题:codevs 2822 爱在心中 解题报告

    这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...

  6. 习题:codevs 1035 火车停留解题报告

    本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...

  7. 习题: codevs 2492 上帝造题的七分钟2 解题报告

    这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...

  8. [置顶] 刘汝佳《训练指南》动态规划::Beginner (25题)解题报告汇总

    本文出自   http://blog.csdn.net/shuangde800 刘汝佳<算法竞赛入门经典-训练指南>的动态规划部分的习题Beginner  打开 这个专题一共有25题,刷完 ...

  9. CH Round #56 - 国庆节欢乐赛解题报告

    最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...

随机推荐

  1. iOS 屏幕适配:autoResizing autoLayout和sizeClass

    1. autoResizing autoresizing是苹果早期的ui布局适配的解决办法,iOS6之前完全可以胜任了,因为苹果手机只有3.5寸的屏幕,在加上手机app很少支持横屏,所以iOS开发者基 ...

  2. G2 DT时代的图形语法 正式发布

    G2有一个高大上的名字叫做:The Grammar Of Graphics——图形语法.它是一个强大的语义化图表生成工具,它提供了一整套图形语法,可以让用户通过简单的语法搭建出无数种图表,并且集成了大 ...

  3. Java连接MongoDB进行增删改查

    1.导入必须的包: 详情看项目:http://pan.baidu.com/s/1cvDAOY 2.通过Myeclipse创建WEB项目 3. 3.bean:创建实体类 package com.bean ...

  4. web前端攻击详解

    前端攻击成因 在web网页的脚本中,有些部分的显示内容会依据外界输入值而发生变化,而如果这些声称html的程序中存在问题,就会滋生名为跨站脚本的安全隐患 XSS跨站脚本攻击: 英文全称cross-si ...

  5. PHP 对象 “==” 与 “===”

    php中对象在内存中的存储方式与java等其他面向对象语言类似,$a = new Person();在内存中表现为$a是堆区中new Person()中的引用 这样当: $a = new Person ...

  6. Android 自动补全提示输入AutoCompleteTextView、 MultiAutoCompleteTextView

    以在搜索框搜索时,自动补全为例: 其中还涉及到一个词,Tokenizer:分词器,分解器. 上效果图: MainActivity.java: package com.joan.testautocoml ...

  7. [Java 基础]字符串

    String类 实例化String对象 String 对象初始化方式有多种. 如下代码中,各种初始化方式的效果是一样的,初始化后,String 对象的内容为 "hello" . p ...

  8. Pig + Ansj 统计中文文本词频

    最近特别喜欢用Pig,拥有能满足大部分需求的内置函数(built-in functions),支持自定义函数(user defined functions, UDF),能load 纯文本.avro等格 ...

  9. Elasticsearch聚合 之 Date Histogram聚合

    Elasticsearch的聚合主要分成两大类:metric和bucket,2.0中新增了pipeline还没有研究.本篇还是来介绍Bucket聚合中的常用聚合--date histogram.参考: ...

  10. HTML5拓扑图形组件设计之道(一)

    HT for Web(http://www.hightopo.com/guide/readme.html)提供了涵盖通用组件.2D拓扑图形组件以及3D引擎的一站式解决方案,正如Hightopo官网所表 ...