题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2874

题目大意:给出n个点,m条边,q个询问,每次询问(u,v)的最短距离,若(u,v)不连通即不在同一颗树上则输出“Not connected”。

解题思路:这题也是模板题,有所不同的是这次给出的是森林而不是一棵树,所以vis数组得稍作修改,标记vis数组的是当前树的编号。下面给出Tarjan和倍增法两种解法。

Tarjan(离线)写法,被MLE坑了,离线写法必须要用静态邻接表,因为虽然n不大,但是q很大,所以如果存储问题邻接表会超内存。

还有突然脑残把dis[x]+dis[y]-2*dis[lca(x,y)]写成dis[x]+dis[y]-dis[lca(x,y)]漏了个2看了半天!!!MDZZ!!!

代码

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int N=1e4+;
const int M=1e6+; struct qnode{
int to,id,next;
}q[M*]; struct node{
int to,w,next;
}edge[N*]; int n,m,cnt,num,idx1,idx2;
int res[M],root[N],vis[N],dis[N],head1[N],head2[N]; void addedge(int u,int v,int w){
edge[idx1].to=v;
edge[idx1].w=w;
edge[idx1].next=head1[u];
head1[u]=idx1++;
} void addq(int u,int v,int id){
q[idx2].to=v;
q[idx2].id=id;
q[idx2].next=head2[u];
head2[u]=idx2++;
} int find(int x){
return root[x]==x?x:root[x]=find(root[x]);
} void init(){
cnt=num=;
idx1=idx2=;
for(int i=;i<=n;i++) root[i]=i;
memset(res,-,sizeof(res));
memset(vis,,sizeof(vis));
memset(dis,,sizeof(dis));
memset(head1,,sizeof(head1));
memset(head2,,sizeof(head2));
} void lca(int u,int num){
//注意这里vis[u]标记的是树的编号,为了判断点是否在同一颗树上
vis[u]=num;
//root[u]=u;
for(int i=head1[u];i;i=edge[i].next){
node t=edge[i];
if(!vis[t.to]){
dis[t.to]=dis[u]+t.w;
lca(t.to,num);
root[t.to]=u;
}
}
for(int i=head2[u];i;i=q[i].next){
qnode t=q[i];
//属于同一颗树
if(vis[t.to]==num)
res[t.id]=dis[t.to]+dis[u]-*dis[find(t.to)];
}
} int main(){
int t;
while(~scanf("%d%d%d",&n,&m,&t)){
init();
for(int i=;i<=m;i++){
int a,b,w;
scanf("%d%d%d",&a,&b,&w);
addedge(a,b,w);
addedge(b,a,w);
}
for(int i=;i<=t;i++){
int a,b;
scanf("%d%d",&a,&b);
addq(a,b,i);
addq(b,a,i);
}
//森林
for(int i=;i<=n;i++){
if(!vis[i]) lca(i,i);
}
for(int i=;i<=t;i++){
if(res[i]==-)
puts("Not connected");
else
printf("%d\n",res[i]);
}
}
return ;
}

倍增法(在线)写法,这个倒是不卡vector了,解决了上面所有问题后,我又脑残了的,我TM忘记调用bz()函数了!!!干瞪着瞪了两个小时两个小时啊!!!

所以这道水题弄了我一个下午。。。。噗!

代码

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int N=1e5+; struct node{
int to,w;
node(int to,int w):to(to),w(w){}
}; int n,m,q;
int fa[N][],depth[N],vis[N],dis[N];
vector<node>v[N]; void init(){
for(int i=;i<=n;i++) v[i].clear();
memset(vis,,sizeof(vis));
memset(depth,,sizeof(depth));
memset(dis,,sizeof(dis));
memset(fa,,sizeof(fa));
} void dfs(int u,int num){
vis[u]=num;
for(int i=;i<v[u].size();i++){
node t=v[u][i];
if(!vis[t.to]){
depth[t.to]=depth[u]+;
fa[t.to][]=u;
dis[t.to]=dis[u]+t.w;
dfs(t.to,num);
}
}
} //倍增,处理fa数组
void bz(){
for(int j=;j<=;j++){
for(int i=;i<=n;i++){
fa[i][j]=fa[fa[i][j-]][j-];
}
}
} int lca(int x,int y){
//保证深度大的点为x
if(depth[x]<depth[y])
swap(x,y);
int dc=depth[x]-depth[y];
for(int i=;i<;i++){
if(<<i&dc) //一个判断,模拟下就会清楚
x=fa[x][i];
}
if(x==y) return x; //如果深度一样,两个点相同,直接返回
for(int i=;i>=;i--){
if(fa[x][i]!=fa[y][i]){ //跳2^i不一样,就跳,否则不跳
x=fa[x][i];
y=fa[y][i];
}
}
return fa[x][];
} int main(){
while(~scanf("%d%d%d",&n,&m,&q)){
init(); //初始化
for(int i=;i<=m;i++){
int a,b,w;
scanf("%d%d%d",&a,&b,&w);
v[a].push_back(node(b,w));
v[b].push_back(node(a,w));
}
for(int i=;i<=n;i++){
if(!vis[i]) dfs(i,i);
}
bz(); //一定别忘了啊!!!
for(int i=;i<=q;i++){
int x,y;
scanf("%d%d",&x,&y);
if(vis[x]!=vis[y])
puts("Not connected");
else
printf("%d\n",dis[x]+dis[y]-*dis[lca(x,y)]);
}
}
return ;
}

HDU 2874 Connections 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 Tarjan)

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

  3. HDU 2874 Connections between cities (LCA)

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

  4. HDU 2874 Connections between cities(LCA)

    题目链接 Connections between cities LCA的模板题啦. #include <bits/stdc++.h> using namespace std; #defin ...

  5. hdu 2874 Connections between cities (并查集+LCA)

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

  6. hdu 2874 Connections between cities 带权lca判是否联通

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

  7. hdu 2874 Connections between cities(st&rmq LCA)

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

  8. HDU——2874 Connections between cities

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

  9. Hdu 2874 Connections between cities

    题意: 城市 道路  没有环 不一定连通的树 求两城市的最短距离 设想一下就是很多小树  那好办 思路: lca离线算法 然后有个技巧就是 每次我们tarjan一棵树不是最后树的节点都访问过并且孩子全 ...

随机推荐

  1. 图解HTTP(六)HTTP首部

    一.HTTP报文的结构: 二.4种首部字段: 1. 通用首部字段 请求报文和响应报文都会使用的首部. 首部字段名 说明 Cache-Control 控制缓存行为 Connection 逐跳首部.连接的 ...

  2. Chapter3 (字符串,向量,数组) --C++Prime笔记

    1.using用法:using namespace ::name;注意事项:一般不在头文件使用using否则很容易导致运用命名空间不对错误. 2.string的方法: ①getline(输入流,str ...

  3. UML类图与类间六种关系表示

    UML类图与类间六种关系表示 1.类与类图 类封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性,操作,关系的对象集合的总称. 类图是使用频率最高的UML图之一. 类图用于描述系统中所包含的 ...

  4. tp 事务处理

    tp的事务开启是非常简单的, 只需要M()->startTrans();//开启事务,M()可以是M('xxx') $m->rollback();//事务回滚 $m->commit( ...

  5. P4782 【模板】2-SAT 问题 && 2-SAT问题

    2-SAT到图论 \(k-SAT\) 是 k-适应性问题(Satisfiability)的简称. \(k-SAT\) 问题(除 \(k = 2\))已被证明为是 \(NP\) 完全问题, 而对于 \( ...

  6. snprintf()解析

    snprintf(ssid_mac,sizeof(ssid_mac),"%s_%02X%02X",ssid,macval[4],macval[5]); ssid_mac = ssi ...

  7. noVNC连接CentOS,以Web方式交付VNC远程连接

    什么是noVNC? noVNC 是一个 HTML5 VNC 客户端,采用 HTML 5 WebSockets, Canvas 和 JavaScript 实现,noVNC 被普遍用在各大云计算.虚拟机控 ...

  8. jenkins+testNg+maven+git+selenium自动化集成

    准备环境,提前安装好Jenkins及git,maven插件 1.首先我们新建一个maven的工程,并且在pom.xml中配置好我们依赖的一些jar包 <?xml version="1. ...

  9. 获取assets文件内容,raw内容

    1.均采用流的方式获取里面的内容 assets context.getAssets().open(“fileName”); raw InputStream inputStream = context. ...

  10. Django 2.0.1 官方文档翻译: 文档目录 (Page 1)

    Django documentation contents 翻译完成后会做标记. 文档按照官方提供的内容一页一页的进行翻译,有些内容涉及到其他节的内容,会慢慢补上.所有的翻译内容按自己的理解来写,尽量 ...