1. 程式人生 > >[HDU2874]Connections between cities

[HDU2874]Connections between cities

true scan == pac %d names std head put

題目大意:給你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