zoukankan      html  css  js  c++  java
  • [HDU2874]Connections between cities

    题目大意:给你n个节点的森林(注意不是一棵树),m条路径的长度,c个询问,要你回答每个询问两个点i和j的最短距离,或者回答没有连接。

    解题思路:对于每个节点,求出其到根的距离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
    ",ans[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    eclipse中的TODO和FIXME
    使用mui框架后a标签无法跳转
    java.lang.OutOfMemoryError: Java heap space异常
    mysql中表触发器的简单使用
    编写第一个 Java 程序
    QDialog类exec()与show()的区别
    Qt中信号槽connect的多种类型
    2.3 UML活动图
    2.2 UML用例模型
    2.1 uml序言
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7147259.html
Copyright © 2011-2022 走看看