题目链接: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. Luogu P3251 [JLOI2012]时间流逝 期望dp

    题面 题面 题解 期望\(dp\)好题! 今年\(ZJOI\)有讲过这题... 首先因为\(T\)只有\(50\),大力\(dfs\)后发现,可能的状态数最多只有\(20w\)左右,所以我们就可以大力 ...

  2. 使用Java API的5个技巧

    原文出处:CSDN邓帅 本文介绍了一些关于Java API安全和性能方面的简单易用的技巧,其中包括保证API Key安全和开发Web Service方面中在框架方面选择的一些建议. 程序员都喜欢使用A ...

  3. Java基础-IO流对象之转换流(InputStreamReader与OutoutStreamWriter)

    Java基础-IO流对象之转换流(InputStreamReader与OutoutStreamWriter) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.转换流概述 我们之前 ...

  4. Java基础-程序流程控制第二弹(循环结构)

    Java基础-程序流程控制第二弹(循环结构) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 流程控制有三种基本结构:顺序结构,选择结构和循环结构.一个脚本就是顺序结构执行的,选择结 ...

  5. day6 方法

    1.方法是一段可重复调用的代码段,今天学习的方法可以由主方法直接调用,所以加入public static关键字修饰. 2.方法的重载为方法名相同,参数的类型或个数不同.

  6. ASP.NET Core的身份认证框架IdentityServer4--(5)自定义用户登录(使用官网提供的UI)

    IdentityServer官方提供web页面,可以根据需求修改样式.具体UI下载跟配置参考官网文档. 文档地址:https://identityserver4.readthedocs.io/en/r ...

  7. [SDOI2016 Round1] 数字配对

    COGS 2221. [SDOI2016 Round1] 数字配对 http://www.cogs.pro/cogs/problem/problem.php?pid=2221 ★★★   输入文件:m ...

  8. 基于 Cocos2d-x-lua 的游戏开发框架 Dorothy 简介

    基于 Cocos2d-x-lua 的游戏开发框架 Dorothy 简介 概述 Dorothy 是一个在 Cocos2d-x-lua 基础上发展起来的分支, 它去掉 Cocos2d-x-lua 那些过多 ...

  9. 基本控件文档-UIKit结构图

    CHENYILONG Blog 基本控件文档-UIKit结构图 Fullscreen   UIKit结构图 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博htt ...

  10. 《C语言程序设计基础I》秋季学习总结

    希望下学期比这学期轻松,学习能力上升,只是越发丰富. 一步一步的走踏实了