题目链接: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. BZOJ 4827 循环卷积

    题意:求两个手环任意旋转对应位置的差值+c的平方最小 设b旋转到k最小,那么先将b扩张一倍构成一圈,那么答案式子就是 将这个式子展开一下,事情就变得有趣了起来 这个式子将a[ ]翻转可以化成卷积形式 ...

  2. vue 混入的理解

  3. python---CRM用户关系管理

    Day1:项目分析 一:需求分析 二:CRM角色功能介绍 三:业务场景分析 销售: .销售A 从百度推广获取了一个客户,录入了CRM系统,咨询了Python课程,但是没有报名 .销售B 从qq群获取一 ...

  4. ubuntu 使用小技巧

    1. 查看网速 ethstatus ubuntu下用ethstatus可以监控实时的网卡带宽占用.这个软件能显示当前网卡的 RX 和 TX 速率,单位是Byte 安装 ethstatus 软件 sud ...

  5. 使用 Collections 实现排序 sort方法 对List 实体类实现Comparable类 示例

    package com.test.jj; import java.util.ArrayList; import java.util.Collections; public class Test { A ...

  6. isscroll插件 实现下拉加载 上啦刷新 转

    http://www.jb51.net/article/98394.htm 下面是别人的代码 <!DOCTYPE html> <html> <head> <m ...

  7. Java并发编程原理与实战二十一:线程通信wait&notify&join

    wait和notify wait和notify可以实现线程之间的通信,当一个线程执行不满足条件时可以调用wait方法将线程置为等待状态,当另一个线程执行到等待线程可以执行的条件时,调用notify可以 ...

  8. spring-mvc Mybatis插件打印SQL

    代码: package com.chainup.exchange.service.adapter; import com.chainup.exchange.service.impl.AccountSe ...

  9. ArcGis数据分类(ClassBreaksDefinition)

    文章转载自:Arcgis数据分类那些事儿 数据分类.地图分级(Classification)通常用于Choropleth Map(面量图)的制作中,是专题制图中最初,也是最基本的一个步骤.没有进行过分 ...

  10. 微信小程序开发教程(六)配置——app.json、page.json详解

    全局配置:app.json 微信小程序的全局配置保存在app.json文件中.开发者通过使用app.json来配置页面文件(pages)的路径.窗口(window)表现.设定网络超时时间值(netwo ...