题目链接

给n个城市, m条边, q个询问, 每个询问, 输出城市a和b的最短距离, 如果不联通, 输出not connected。

用并查集判联通, 如果不连通, 那么两个联通块之间加一条权值很大的边。 然后树链剖分.....

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-;
const int mod = 1e9+;
const int inf = ;
const int dir[][] = { {-, }, {, }, {, -}, {, } };
const int maxn = ;
int head[maxn*], fa[maxn], son[maxn], sz[maxn], deep[maxn], top[maxn], w[maxn], f[maxn], cnt, num;
ll sum[maxn<<];
struct node
{
int to, nextt, w;
}e[maxn*];
struct ed
{
int u, v;
ll w;
ed(){}
ed(int u, int v, ll w):u(u),v(v),w(w){}
}edge[maxn];
void init() {
mem1(head);
num = cnt = ;
}
void add(int u, int v, int w) {
e[num].to = v, e[num].nextt = head[u], e[num].w = w, head[u] = num++;
}
void dfs1(int u, int fa) {
sz[u] = ;
deep[u] = deep[fa]+;
son[u] = -;
f[u] = fa;
for(int i = head[u]; ~i; i = e[i].nextt) {
int v = e[i].to;
if(v == fa)
continue;
dfs1(v, u);
sz[u] += sz[v];
if(son[u]==-||sz[v]>sz[son[u]])
son[u] = v;
}
}
void dfs2(int u, int tp) {
w[u] = ++cnt, top[u] = tp;
if(~son[u])
dfs2(son[u], tp);
for(int i = head[u]; ~i; i = e[i].nextt) {
int v = e[i].to;
if(v == f[u]||v == son[u])
continue;
dfs2(v, v);
}
}
void pushUp(int rt) {
sum[rt] = sum[rt<<]+sum[rt<<|];
}
void update(int p, ll val, int l, int r, int rt) {
if(l == r) {
sum[rt] = val;
return ;
}
int m = l+r>>;
if(p<=m)
update(p, val, lson);
else
update(p, val, rson);
pushUp(rt);
}
ll query(int L, int R, int l, int r, int rt) {
if(L<=l&&R>=r) {
return sum[rt];
}
int m = l+r>>;
ll ret = ;
if(L<=m)
ret += query(L, R, lson);
if(R>m)
ret += query(L, R, rson);
return ret;
}
ll find(int u, int v) {
int f1 = top[u], f2 = top[v];
ll ret = ;
while(f1 != f2) {
if(deep[f1]<deep[f2]) {
swap(f1, f2);
swap(u, v);
}
ret += query(w[f1], w[u], , cnt, );
u = f[f1];
f1 = top[u];
}
if(u == v)
return ret;
if(deep[u]>deep[v])
swap(u, v);
ret += query(w[son[u]], w[v], , cnt, );
return ret;
}
int findd(int u) {
return fa[u] == u?u:findd(fa[u]);
}
int main()
{
int n, m, q, x, y, z;
while(cin>>n>>m>>q) {
init();
int ecnt = ;
for(int i = ; i<=n; i++)
fa[i] = i;
for(int i = ; i<m; i++) {
scanf("%d%d%d", &x, &y, &z);
add(x, y, z);
add(y, x, z);
edge[ecnt++] = ed(x, y, z);
x = findd(x);
y = findd(y);
if(x!=y)
fa[x] = y;
}
x = findd();
for(int i = ; i<=n; i++) {
y = findd(i);
if(y!=x) {
fa[y] = x;
edge[ecnt++] = ed(x, y, (ll)1e12);
add(x, y, inf);
add(y, x, inf);
}
}
dfs1(, );
dfs2(, );
for(int i = ; i<ecnt; i++) {
if(deep[edge[i].u]>deep[edge[i].v]) {
swap(edge[i].u, edge[i].v);
}
update(w[edge[i].v], edge[i].w, , cnt, );
}
while(q--) {
scanf("%d%d", &x, &y);
ll ans = find(x, y);
if(ans>=1e12) {
puts("Not connected");
} else {
printf("%d\n", ans);
}
}
} return ;
}

hdu 2874Connections between cities LCA的更多相关文章

  1. hdu 2874 Connections between cities [LCA] (lca->rmq)

    Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (J ...

  2. HDU 2874 Connections between cities (LCA)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2874 题意是给你n个点,m条边(无向),q个询问.接下来m行,每行两个点一个边权,而且这个图不能有环路 ...

  3. HDU 2874 Connections between cities(LCA Tarjan)

    Connections between cities [题目链接]Connections between cities [题目类型]LCA Tarjan &题意: 输入一个森林,总节点不超过N ...

  4. Connections between cities HDU - 2874(最短路树 lca )

    题意: 给出n个点m条边的图,c次询问 求询问中两个点间的最短距离. 解析: Floyd会T,所以用到了最短路树..具体思想为: 设k为u和v的最近公共祖先 d[i] 为祖结点到i的最短距离  则di ...

  5. HDU 4822 Tri-war(LCA树上倍增)(2013 Asia Regional Changchun)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4822 Problem Description Three countries, Red, Yellow ...

  6. HDU 3966 dfs序+LCA+树状数组

    题目意思很明白: 给你一棵有n个节点的树,对树有下列操作: I c1 c2 k 意思是把从c1节点到c2节点路径上的点权值加上k D c1 c2 k 意思是把从c1节点到c2节点路径上的点权值减去k ...

  7. Connections between cities LCA

    Problem Description After World War X, a lot of cities have been seriously damaged, and we need to r ...

  8. hdu-2874 Connections between cities(lca+tarjan+并查集)

    题目链接: Connections between cities Time Limit: 10000/5000 MS (Java/Others)     Memory Limit: 32768/327 ...

  9. hdu Dylans loves tree [LCA] (树链剖分)

    Dylans loves tree view code#pragma comment(linker, "/STACK:1024000000,1024000000") #includ ...

随机推荐

  1. 自己定义View常处理的回调函数

    onFinishInflate() 当View中全部的子控件均被映射成xml后触发 onMeasure(int, int) 确定全部子元素的大小 onLayout(boolean, int, int, ...

  2. WPF datagrid 初学

    <Window x:Class="WpfDemo.WinDataGrid" xmlns="http://schemas.microsoft.com/winfx/20 ...

  3. 指针和Const限定符

    指针和Const限定符 1.指向const对象的指针 如果指针指向的是const对象,则不允许使用指针来改变其所指的const值.C++要求指向const对象的指针具有const特性. const d ...

  4. EJBCA认证系统结构及相关介绍

    写作此文的主要目的是记录下EJBCA认证系统的系统结构及相关部件作用的介绍,方便后面查阅使用.

  5. 七种Prolog解释器/编译器

    http://blog.sina.com.cn/s/blog_494e45fe0100lh1v.html PROLOG 人工智能领域常用的语言,开发自然语言分析,专家系统,以及所有和智能有关的程序,都 ...

  6. JavaScript知识(二)

    你要保守你心,胜过保守一切,因为一生的果效,是由心发出的.————O(∩_∩)O... ...O(∩_∩)O...老师因有事下午没来上课,今天就只把中午讲的知识总结一下.由于昨天只是讲了JavaScr ...

  7. 现在有m组n个有序数组,例如{1,2,3,4},{2,3,4,6},{1,3,5,7},在这些数组中选择第k小的数据,然后返回这个值

    问题描述:现在有m组n个有序数组,例如{1,2,3,4},{2,3,4,6},{1,3,5,7},在这些数组中选择第k小的数据,然后返回这个值 思路:参照两个数组归并的过程,每次选取最小的数据进行比较 ...

  8. BZOJ 3774: 最优选择( 最小割 )

    最小割...二分染色然后把颜色不同的点的源汇反过来..然后就可以做了. 某个点(x,y): S->Id(x,y)(回报), Id(x,y)->T(代价), Id(i,j)&& ...

  9. ODI中的CDC

    ODI中的CDC是通过一组所谓的日志知识模块(Journal Knowledge Module,JKM)实现的,在项目中加在了这些模块后,就可以在接口设计时选择全量数据,还是变化数据.   ODI共提 ...

  10. PCB板上镀镍厚度

    PCB制造工业由于成本.周期时间和材料兼容性的原因,对减少沉淀在电路板上的镍的数量感兴趣.最小镍的规格应该帮助防止铜对金表面的扩散.保持良好的焊接点强度.和较低的接触电阻.最大镍的规格应该允许板制造的 ...