思路:
LCA裸题。本来是帮pechpo调错,结果自己写了半天…
设$dis_x$是点$x$到根结点距离,不难想到两点$u$、$v$之间最短距离等于$dis_u+dis_v-dis_{LCA(u,v)}\times 2$。
然后我们可以用Tarjan做,然后发现MLE了。
以为是这题卡vector的内存,于是改成了链式前向星,还是MLE。
后来发现题目的内存限制只有32M,算了算,如果将数据离线保存下来,大约有20000K左右,再加上函数里面的栈,似乎确实有点危险。
最后改成用ST做,只用了5852KB。

 #include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
inline int getint() {
char ch;
while(!isdigit(ch=getchar()));
int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
inline int flog2(const float x) {
return ((unsigned&)x>>&)-;
}
const int V=,logV=;
struct Edge {
int to,w,next;
};
Edge edge[V<<];
int e[V],esz;
inline void add_edge(const int u,const int v,const int w) {
esz++;
edge[esz]=(Edge){v,w,e[u]};
e[u]=esz;
}
bool vis[V];
int dis[V],dep[V];
int anc[V][logV];
inline void init() {
esz=;
memset(vis,,sizeof vis);
memset(dis,,sizeof dis);
memset(anc,,sizeof anc);
memset(dep,,sizeof dep);
memset(e,,sizeof e);
}
void dfs(const int x,const int par) {
vis[x]=true;
anc[x][]=par;
dep[x]=dep[par]+;
for(int i=e[x];i;i=edge[i].next) {
int &y=edge[i].to;
if(y==par) continue;
dis[y]=dis[x]+edge[i].w;
dfs(y,x);
}
}
int LCA(int a,int b) {
if(dep[a]<dep[b]) std::swap(a,b);
for(int i=flog2(dep[a]);i>=;i--) {
if(dep[a]-(<<i)>=dep[b]) a=anc[a][i];
}
if(a==b) return a;
for(int i=flog2(dep[a]);i>=;i--) {
if(anc[a][i]!=anc[b][i]) a=anc[a][i],b=anc[b][i];
}
return anc[a][];
}
int main() {
int n,m,q;
while(~scanf("%d%d%d",&n,&m,&q)) {
init();
while(m--) {
int u=getint(),v=getint(),w=getint();
add_edge(u,v,w);
add_edge(v,u,w);
}
for(int i=;i<=n;i++) {
if(!vis[i]) dfs(i,);
}
for(int j=;j<=flog2(n);j++) {
for(int i=;i<=n;i++) {
anc[i][j]=anc[anc[i][j-]][j-];
}
}
while(q--) {
int u=getint(),v=getint();
if(int lca=LCA(u,v)) {
printf("%d\n",dis[u]+dis[v]-dis[lca]*);
}
else {
puts("Not connected");
}
}
}
return ;
}

本来用Tarjan算法是MLE的,当时是用了三个数组$qx[Q]$,$qy[Q]$,$lca[Q]$,分别存储每一个$x$,$y$和$LCA(x,y)$,Tarjan的时候求出LCA。最后答案输出的时候计算距离。
后来考虑在Tarjan的同时直接将它们之间的距离求出来,这样一下子就节省了两个数组,最后跑了29376K,还是勉强卡过去。

 #include<cstdio>
#include<cctype>
#include<cstring>
inline int getint() {
char ch;
while(!isdigit(ch=getchar()));
int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int V=,E=,Q=;
struct Edge {
int to,w,next;
};
Edge edge[E<<];
int e[V],esz;
inline void add_edge(int u,int v,int w) {
esz++;
edge[esz]=(Edge){v,w,e[u]};
e[u]=esz;
}
struct Query {
int to,id,next;
};
Query query[Q<<];
int q[V],qsz;
inline void add_query(int u,int v,int id) {
qsz++;
query[qsz]=(Query){v,id,q[u]};
q[u]=qsz;
}
class DisjointSet {
private:
int anc[V];
public:
void reset() {
for(int i=;i<V;i++) anc[i]=i;
}
int Find(int x) {
return x==anc[x]?x:anc[x]=Find(anc[x]);
}
void Union(int x,int y) {
anc[Find(x)]=Find(y);
}
bool isConnected(int x,int y) {
return Find(x)==Find(y);
}
};
DisjointSet s;
int ans[Q];
int vis[V];
int dis[V]={};
int root;
void Tarjan(int x,int par) {
vis[x]=root;
for(int i=e[x];i;i=edge[i].next) {
int y=edge[i].to;
if(y!=par) {
dis[y]=dis[x]+edge[i].w;
Tarjan(y,x);
s.Union(y,x);
}
}
for(int i=q[x];i;i=query[i].next) {
int y=query[i].to;
if(vis[y]==root) {
ans[query[i].id]=dis[x]+dis[y]-dis[s.Find(y)]*;
}
}
}
inline void init() {
s.reset();
esz=qsz=;
for(int i=;i<Q;i++) ans[i]=-;
memset(vis,,sizeof vis);
memset(e,,sizeof e);
memset(q,,sizeof q);
}
int main() {
int n,m,q;
while(~scanf("%d%d%d",&n,&m,&q)) {
init();
while(m--) {
int u=getint(),v=getint(),w=getint();
add_edge(u,v,w);
add_edge(v,u,w);
}
for(int i=;i<q;i++) {
int u=getint(),v=getint();
add_query(u,v,i);
add_query(v,u,i);
}
for(int i=;i<=n;i++) {
if(!vis[i]) {
root=i;
Tarjan(i,);
}
}
for(int i=;i<q;i++) {
if(~ans[i]) {
printf("%d\n",ans[i]);
}
else {
puts("Not connected");
}
}
}
return ;
}

[HDU2874]Connections between cities的更多相关文章

  1. hdu-2874 Connections between cities(lca+tarjan+并查集)

    题目链接: Connections between cities Time Limit: 10000/5000 MS (Java/Others)     Memory Limit: 32768/327 ...

  2. [hdu2874]Connections between cities(LCA+并查集)

    题意:n棵树,求任意两点的最短距离. 解题关键:并查集判断两点是否位于一棵树上,然后求最短距离即可.此题可以直接对全部区间直接进行st表,因为first数组会将连接的两点的区间表示出来. //#pra ...

  3. HDU2874 Connections between cities 最近公共祖先

    第一次按常规的方法求,将所有的查询的u,v,和最近公共祖先都保存起来,然后用tarjan+并查集求最近公共祖先.因为询问的次数过多,所以在保存查询的时候总是MLE,后来参考了一下别人的代码,才突然觉悟 ...

  4. hdu 2874 Connections between cities [LCA] (lca->rmq)

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

  5. Connections between cities

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

  6. HDU 2874 Connections between cities(LCA Tarjan)

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

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

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

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

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

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

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

随机推荐

  1. [Java] Servlet工作原理之一:体系结构及其容器

    一.Servlet体系结构 在 servlet-api.jar (2.5) 中有两个包:javax.servlet 和 javax.servlet.http             1 Servlet ...

  2. bzoj千题计划272:bzoj4557: [JLoi2016]侦察守卫

    http://www.lydsy.com/JudgeOnline/problem.php?id=4557 假设当前到了x的子树,现在是合并 x的第k个子树 f[x][j] 表示x的前k-1个子树该覆盖 ...

  3. [iOS]图片高清度太高, 导致内存过大Crash

    先说一下状况, 后台提供的图片太高清了, 每个图片都在2-4MB, iOS上每个页面需要同时下载并展示10-15张. 这个时候, 如果我多滑动collectionView几次, 直接App就崩溃了(r ...

  4. 20155207王雪纯 2016-2017-2 《Java程序设计》第六周学习总结

    20155207 2016-2017-2 <Java程序设计>第六周学习总结 教材学习内容总结 第10章 输入/输出 10.1 InputStream与OutputStream 10.1. ...

  5. es6笔记(4) Set数据结构

    概要 介绍: 集合是由一组无序且唯一的项组成的,这个数据结构使用了与有限集合相同的数学概念,应用在计算机的数据结构中. ES6提供了数据结构Set.它类似于数组,但是没有重复的值. 特点: key与v ...

  6. ListView position

    在使用listview的时候,我们经常会在listview的监听事件中,例如OnItemClickListener(onItemClick)中,或listview的adapter中(getView.g ...

  7. python2.7中MySQLdb的安装与使用详解

    Python2.7中MySQLdb的使用 import MySQLdb #1.建立连接 connect = MySQLdb.connect( '127.0.0.1', #数据库地址 'root', # ...

  8. flask基础之session原理详解(十)

    前言 flask_session是flask框架实现session功能的一个插件,用来替代flask自带的session实现机制,flask默认的session信息保存在cookie中,不够安全和灵活 ...

  9. andriod 自定义来电界面功能

    由于近期所做一个项目需要做类似于“来电秀”的功能,所以上网搜索了一些相关资料,加上自己的一些想法,做了一个Demo.一下是我对该功能实现的一些想法,不对的地方欢迎各位指出.最后我会给出Demo 的源代 ...

  10. Ubuntu环境下TensorBoard 可视化 不显示数据问题 No scalar data was found...(作者亲测有效)(转)

    TensorBoard:Tensorflow自带的可视化工具.利用TensorBoard进行图表可视化时遇到了图表不显示的问题. 环境:Ubuntu系统 运行代码,得到TensorFlow的事件文件l ...