思路:
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. UnicodeDecodeError gbk codec can't decode byte in position illegal multibyte sequence

    UnicodeDecodeError:'gbk' codec can't decode byte in position : illegal multibyte sequence 觉得有用的话,欢迎一 ...

  2. angularJs实现下拉框多选

    话不多说,直接上干货. 肯定需要下拉选插件.必须引入的是   注意 先后顺序 select2.css select2-bootstrap.css select2.min.js angular.min. ...

  3. SpringMVC关于ajax提交400错误(后台获取为null)

    400错误有三种情况 1:请求的数据量过大,不过这种情况一般很少见. 2:请求的data参数有误,确保每一个参数都能请求到. 注释:之前小白出现400错误,后台获取参数为null是因为第三种情况,经过 ...

  4. CF&&CC百套计划4 Codeforces Round #276 (Div. 1) E. Sign on Fence

    http://codeforces.com/contest/484/problem/E 题意: 给出n个数,查询最大的在区间[l,r]内,长为w的子区间的最小值 第i棵线段树表示>=i的数 维护 ...

  5. bzoj千题计划179:bzoj1237: [SCOI2008]配对

    http://www.lydsy.com/JudgeOnline/problem.php?id=1237 如果没有相同的数不能配对的限制 那就是排好序后 Σ abs(ai-bi) 相同的数不能配对 交 ...

  6. ASP.NET生成二维码

    下面使用ThoughtWorks.QRCode.dll这个类库,实现生成二维码 使用时需要增加:下面三个命名空间 using ThoughtWorks.QRCode.Codec; using Thou ...

  7. java代码实现图片处理功能。对图片质量进行压缩。

    java图片处理有点头疼,找了很多资料.在这里进行一个汇总,记录下个人的体验,也希望对大家有所帮助. 需求:浏览的图片需要在1M一下. 1.真正对图片的质量进行压缩的(不是通过修改图片的高,宽进行缩小 ...

  8. 20155328 2016-2017-2 《Java程序设计》第六周 学习总结

    20155328 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 根据不同的分类标准,IO可分为:输入/输出流:字节/字符流:节点/处理流. 在不使用Inpu ...

  9. iOS8 自定义navigationItem.titleView

    navigationBar其实有三个子视图,leftBarButtonItem,rightBarButtonItem,以及titleView.前两种的自定义请参考http://www.cnblogs. ...

  10. (FFT)A+B Problem

    题目链接:https://cn.vjudge.net/contest/280041#problem/B 题目大意:给你n个数,然后让你找满足a[i] + a[j] = a[k] 的情况总数. 具体思路 ...