思路:
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. Spring MVC 中 @ModelAttribute 注解的妙用

    Spring MVC 中 @ModelAttribute 注解的妙用 Spring MVC 提供的这种基于注释的编程模型,极大的简化了 web 应用的开发.其中 @Controller 和 @Rest ...

  2. HDU 1730 类NIM模型

    两者间的间距就是可取石子数,因为对于行内黑白相连的局面该子游戏已经结束了因为此时不管先手再怎么移都是必败,SG=0的终止态 /** @Date : 2017-10-14 21:46:21 * @Fil ...

  3. Java面试题系列(一)描述一下JVM加载class文件的原理机制

    JVM系列第4讲:从源代码到机器码,发生了什么? https://www.cnblogs.com/chanshuyi/p/jvm_serial_04_from_source_code_to_machi ...

  4. SQL Server 的字段不为NULL时唯一

    CREATE UNIQUE NONCLUSTERED INDEX 索引名称ON 表名(字段) WHERE 字段 is not null SQL Server 2008+ 支持

  5. HDU 2086 A=? 数学题

    题目描述:有一个公式,Ai = (Ai-1 + Ai+1)/2 - Ci (i = 1, 2, 3, .... n).,如果给出A0, An+1, 和 C1, C2, .....Cn要你计算出A1是多 ...

  6. 第6月第19天 lua动态链接库(luaopen_*函数的使用) skynet

    1. 给这个测试库取名为dylib,它包含一个函数add.lua中这样使用: local dylib = require "dylib.test"    local c = dyl ...

  7. Sql语句 表中相同的记录(某个字段)只显示一条,按照时间排序显示最大或最小

    原始表数据:

  8. IE下常见兼容性问题总结

    概述 本小菜平时主要写后台程序,偶尔也会去写点前端页面,写html.css.js的时候,会同时开着ie6.ie7.ie8.ie9.chrome.firefox等浏览器进行页面测试,和大部分前端开发一样 ...

  9. js自定制周期函数

    function mySetInterval(fn, milliSec,count){ function interval(){ if(typeof count==='undefined'||coun ...

  10. 001_关于选中的磁盘具有MBR分区表。在 EFI 系统上,Windows 只能安装到 GPT 磁盘。问题解决

    问题: 今天我的diy电脑重装系统时,遇到了一个棘手的问题.在选择安装分区的时候,提示有这样的错误. Windows 无法安装到这个磁盘.选中的磁盘具有MBR分区表.在 EFI 系统上,Windows ...