题目链接

给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. Validform表单验证的完美解决方案,推荐给大家

    http://validform.rjboy.cn/ 功能简介: 可以在input上直接绑定正则,可以自定义datatype,自定义datatype可以是正则,也可以是函数,datatype可以累加或 ...

  2. apktool 反翻译错误

    -出现 UndefinedResObject Exception : 这是因为被反编译的apk中有当前的framework不支持的属性:解决方式如下: 1.删除C:\Users\Administrat ...

  3. web server服务器

    使用最多的 web server服务器软件有两个:微软的信息服务器(iis),和Apache. 通俗的讲,Web服务器传送(serves)页面使浏览器可以浏览,然而应用程序服务器提供的是客户端应用程序 ...

  4. Django一对多,多对多操作

    简要说明 Django里面的数据库操作O2O&M2M,一般归属于models管理 使用场景 一对一:在某表中创建一行数据时,有一个单选的下拉框(下拉框中的内容被用过一次就消失了).//两个表的 ...

  5. IOS 特定于设备的开发:Core Motion基础

    Core Motion框架集中了运动数据处理.该框架是在IOS 4 SDK中引入的,用于取代accelerometer加速计访问.它提供了对3个关键的机载传感器的集中式监测.这些传感器有陀螺仪.磁力计 ...

  6. delete了,析构函数却没有调用

    析构函数在对象的生命结束时,会自动调用,大家所熟知的智能指针就是根据析构函数的这种特性而实现的,包括Qt的内存管理机制,也都是利用了析构函数的这一机制来实现的.c++创始人Bjarne Stroust ...

  7. 通过focusInEvent和eventFilter两种方法改写控件颜色(自定义控件就是这么来的)

    http://www.cnblogs.com/hicjiajia/archive/2012/05/30/2526768.html http://www.cnblogs.com/hicjiajia/ar ...

  8. file_get_contents 超时设置

    <?php $ctx = stream_context_create( array( 'http' => array( 'timeout' => 1 //设置一个超时时间,单位为秒 ...

  9. openStack deep dive,Retake Policy

    Method of Payment: visa MasterCard American Express Discover

  10. github中的ssh配置

    1.配置git信息 设置git的user name和email: $ git config --global user.name "tigerjibo"$ git config - ...