题目链接

给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. ubuntu系统安装FTP

    Ubuntu安装vsftp软件 1.更新软件源 首先须要更新系统的软件源,便捷工具下载地址:http://help.aliyun.com/manual?spm=0.0.0.0.zJ3dBU&h ...

  2. IdeasToComeTrue

    灵感这玩意,果真是有的吧.不考虑什么架构和盈利模式,就只是想到的有趣,随便写写,以飨流年. 我的头脑风暴:爱玩儿aiWaner 2015/08/22 换书: 每个人可能有很多闲置图书,自己看完了觉得好 ...

  3. 完全卸载oracle10G/11G步骤

    从oracle前台卸载oracle后重新安装会安装不了,需要完全卸载: 完全卸载oracle11g步骤:1. 开始->设置->控制面板->管理工具->服务 停止所有Oracle ...

  4. svn的使用总结(待补充)

    1.直接选择文件右键--diff比较的是(本地上次与svn同步的文件)与工作区的比较.(每次更新后,会自动备份本次更新的文件) 2.若是要跟 svn最新版本比较的话,可以选择版本找到对应文件,点击sh ...

  5. Control的Invoke和BeginInvoke详解

    (一)Control的Invoke和BeginInvoke 我们要基于以下认识: (1)Control的Invoke和BeginInvoke与Delegate的Invoke和BeginInvoke是不 ...

  6. 为什么IIS中找不到.net framework 4.5(转)

    .net 4.5是4.0的update,所以直接用4.0部署就可以了 .NET 4.5 is an in-place replacement for .NET 4.0, When .NET 4.5 i ...

  7. Toast的替代者Snackbar

    在Android design support library中,SnackBar的使用: Part 2 – Welcome Snackbar, Goodbye Toast! BY PARESH MA ...

  8. Node.js 启动小结

    配置环境变量: cmd-------> 启动dyson服务 在项目的路径下 如open cmd进入open目录执行npm start命令 在浏览器下输入访问地址:http://localhost ...

  9. yii2.0 从控制器到视图的输出

    在controllers/SiteController.php文件中,添加 public function actionSay($message = 'Hello') { return $this-& ...

  10. 利用 onload 事件监控跨站资源

    用过 CSP 的都很郁闷,上报的只有违规的站点名,却没有具体路径.这是缺陷,还是特意的设计? 显然,CSP 是为安全定制的,里面的规范自然要严格制定,否则就会带来新的安全问题.如果支持详细路径的上报, ...