[HDU2874]Connections between cities
Posted Mrsrz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HDU2874]Connections between cities相关的知识,希望对你有一定的参考价值。
题目大意:给你n个节点的森林(注意不是一棵树),m条路径的长度,c个询问,要你回答每个询问两个点i和j的最短距离,或者回答没有连接。
数据范围:2<=n<=10000,0<=m<10000,1<=c<=1000000
解题思路:对于每个节点,求出其到根的距离a[i],然后求两点的最近公共祖先LCA,最后的答案为$a[i]+a[j]-2*a[LCA(i,j)]$。
我用的是Tarjan算法。
注意此题可能出现两个相同点的情况,需要注意一些细节,或者特判。
C++ Code:
#include<cstdio> #include<cstring> using namespace std; int n,m,c,cnt=0,cntq=0,head[10002],headq[1000002],fa[10002],a[10002]={0}; bool vis[10002],all[10002]; struct edge{ int to,dist,next; }e[20004]; struct Q{ int to,next; }q[2000004]; int ans[1000002]; void addedge(int from,int to,int dist){ cnt++; e[cnt].to=to; e[cnt].dist=dist; e[cnt].next=head[from]; head[from]=cnt; cnt++; e[cnt].to=from; e[cnt].dist=dist; e[cnt].next=head[to]; head[to]=cnt; } int dad(int x){ return(fa[x]==x)?(x):(fa[x]=dad(fa[x])); } void addq(int x,int y){ cntq++; q[cntq].to=y; q[cntq].next=headq[x]; headq[x]=cntq; cntq++; q[cntq].to=x; q[cntq].next=headq[y]; headq[y]=cntq; } void lca(int root,int pre){ fa[root]=root; for(int i=head[root];i;i=e[i].next){ int p=e[i].to; if(p!=pre){ a[p]=a[root]+e[i].dist; lca(p,root); } } vis[root]=all[root]=true; for(int i=headq[root];i;i=q[i].next){ int p=q[i].to; if(vis[p]){ int LCA=dad(p); ans[(i+1)/2]=a[root]+a[p]-a[LCA]*2; } } fa[root]=pre; } int main(){ while(scanf("%d%d%d",&n,&m,&c)!=EOF){ cnt=cntq=0; memset(a,0,sizeof(a)); memset(fa,0,sizeof(fa)); memset(head,0,sizeof(head)); memset(headq,0,sizeof(headq)); memset(e,0,sizeof(e)); memset(q,0,sizeof(q)); memset(ans,-1,sizeof(ans)); memset(all,0,sizeof(all)); for(int i=1;i<=m;i++){ int from,to,dist; scanf("%d%d%d",&from,&to,&dist); addedge(from,to,dist); } for(int i=1;i<=c;i++){ int x,y; scanf("%d%d",&x,&y); addq(x,y); } for(int i=1;i<=n;i++) if(!all[i]){ memset(vis,0,sizeof(vis)); lca(i,0); } for(int i=1;i<=c;i++) if(ans[i]==-1)puts("Not connected");else printf("%d\n",ans[i]); } return 0; }
以上是关于[HDU2874]Connections between cities的主要内容,如果未能解决你的问题,请参考以下文章
HDU 2874 Connections between cities(LCA离线算法实现)
[HDU2874]Connections between cities
[HDU2874]Connections between cities
HDU2874 Connections between cities(并查集+倍增LCA算法求森林最短路)