HDU 2874 Connections between cities(LCA离线算法实现)

http://acm.hdu.edu.cn/showproblem.php?pid=2874

题意:

求两个城市之间的距离。

思路:

LCA题,注意原图可能不连通。

如果不了解离线算法的话,可以看我之前博客写的解释http://www.cnblogs.com/zyb993963526/p/7295894.html

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<sstream>
  6 #include<vector>
  7 #include<stack>
  8 #include<queue>
  9 #include<cmath>
 10 #include<map>
 11 #include<set>
 12 using namespace std;
 13 typedef long long ll;
 14 typedef pair<int,int> pll;
 15 const int INF = 0x3f3f3f3f;
 16 const int maxn=10000+5;
 17 const int M=1000010;
 18
 19 int n, m, c;
 20 int etot,qtot;
 21 int ehead[maxn];
 22 int qhead[maxn];
 23 int mark[maxn];
 24 int dis[maxn];
 25 int vis[maxn];
 26
 27 int ans[M];
 28 int p[maxn];
 29
 30 struct node
 31 {
 32     int v,w;
 33     int next;
 34 }e[2*maxn];
 35
 36 struct Node
 37 {
 38     int v;
 39     int index;
 40     int next;
 41 }query[2*M];
 42
 43 void addEdge(int u, int v, int w)
 44 {
 45     e[etot].v=v;
 46     e[etot].w=w;
 47     e[etot].next=ehead[u];
 48     ehead[u]=etot++;
 49 }
 50
 51 void addQuery(int u, int v, int i)
 52 {
 53     query[qtot].v=v;
 54     query[qtot].index=i;
 55     query[qtot].next=qhead[u];
 56     qhead[u]=qtot++;
 57 }
 58
 59 int Find(int x)
 60 {
 61     return p[x]==x?x:p[x]=Find(p[x]);
 62 }
 63
 64 void LCA(int u)
 65 {
 66     vis[u]=1;
 67     for(int i=qhead[u];i!=-1;i=query[i].next)
 68     {
 69         int v=query[i].v;
 70         if(vis[v] && !mark[Find(v)])  //mark数组是为了针对非连通图的情况
 71             ans[query[i].index]=dis[u]+dis[v]-2*dis[Find(v)];
 72     }
 73
 74     for(int i=ehead[u];i!=-1;i=e[i].next)
 75     {
 76         int v=e[i].v;
 77         if(!vis[v])
 78         {
 79             dis[v]=dis[u]+e[i].w;
 80             LCA(v);
 81             p[v]=u;
 82         }
 83     }
 84 }
 85
 86 int main()
 87 {
 88     //freopen("in.txt","r",stdin);
 89     while(~scanf("%d%d%d",&n,&m,&c))
 90     {
 91         etot=qtot=0;
 92         memset(qhead,-1,sizeof(qhead));
 93         memset(ehead,-1,sizeof(ehead));
 94         for(int i=1;i<=n;i++)  p[i]=i;
 95
 96         while(m--)
 97         {
 98             int u,v,w;
 99             scanf("%d%d%d",&u,&v,&w);
100             addEdge(u,v,w);
101             addEdge(v,u,w);
102         }
103
104         for(int i=1;i<=c;i++)
105         {
106             int u,v;
107             scanf("%d%d",&u,&v);
108             addQuery(u,v,i);
109             addQuery(v,u,i);
110         }
111
112         memset(ans,-1,sizeof(ans));
113         memset(vis,0,sizeof(vis));
114         memset(mark,0,sizeof(mark));
115         for(int i=1;i<=n;i++)
116         {
117             if(!vis[i])
118             {
119                 dis[i]=0;
120                 LCA(i);
121                 mark[i]=1;
122             }
123         }
124         for(int i=1;i<=c;i++)
125         {
126             if(ans[i]==-1)   puts("Not connected");
127             else printf("%d\n",ans[i]);
128         }
129     }
130     return 0;
131 }
时间: 2024-08-10 23:20:53

HDU 2874 Connections between cities(LCA离线算法实现)的相关文章

HDU 2874 Connections between cities(LCA离线)

 题意:一个森林,询问两个节点距离,若无法到达,输出Not connected. 思路:还是求LCA的思想,只需再对每个询问的两个节点判断是否在一棵树内即可. 有一个问题是这道题的query很大,达到了1000000,所以离线算法空间上比较虚, 然而只会离线的.....于是把int改成short int险过.... #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #

HDU - 2874 Connections between cities(LCA)

题目大意:给出N个点,M条线,Q个询问,询问的是两点之间的最短距离 解题思路:恶心的数据量,一不小心就超空间了 这题给图不是张连通图,是森林,所以计算两点之间的最短距离时还要考虑一下是否在同一棵树中 剩下的就是裸LCA了 #include <cstdio> #include <cstring> #define N 10010 #define M 20010 #define C 2000010 struct Edge{ int to, next, dis; }E[M]; struct

hdu 2874 Connections between cities(lca-&gt;rmq)

Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4425    Accepted Submission(s): 1263 Problem Description After World War X, a lot of cities have been seriously damag

Hdu 2874 Connections between cities

题意: 城市 道路  没有环 不一定连通的树 求两城市的最短距离 设想一下就是很多小树  那好办 思路: lca离线算法 然后有个技巧就是 每次我们tarjan一棵树不是最后树的节点都访问过并且孩子全能找到根嘛 那么我们只要做做做做 做到全部的城市都访问过了  就行了 反正你做这颗小树的时候又不会影响到其他树的 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; i

HDU 2874 Connections between cities (离线LCA)

题目地址:HDU 2874 好坑的一道题..MLE了好长时间....全用了前向星而且把G++改成了C++才过了.. LCA裸题,没什么好说的.. 代码如下; #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #in

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

Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description After World War X, a lot of cities have been seriously damaged, and we need to rebuild those cities. However, some mat

HDU——2874 Connections between cities

Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11927    Accepted Submission(s): 2775 Problem Description After World War X, a lot of cities have been seriously dama

HDU - 2874 Connections between cities (LCA)

After World War X, a lot of cities have been seriously damaged, and we need to rebuild those cities. However, some materials needed can only be produced in certain places. So we need to transport these materials from city to city. For most of roads h

hdu 2874 Connections between cities hdu 2586 How far away ? LCA

两道lca模板题,用的是倍增法,nlogn预处理,logn查询. #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; #define maxn 10100 struct Edge { int u,v,w,next; }e[100100]; int n,m,c; int head[maxn],cnt; int fa[ma