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 ",ans[i]); 128 } 129 } 130 return 0; 131 }