zoukankan      html  css  js  c++  java
  • 最小生成树+LCA【洛谷 P2245】 星际导航

    【洛谷 P2245】 星际导航

    题目描述

    sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好。为了方便起见,我们可以认为宇宙是一张有N 个顶点和M 条边的带权无向图,顶点表示各个星系,两个星系之间有边就表示两个星系之间可以直航,而边权则是航行的危险程度。

    sideman 现在想把危险程度降到最小,具体地来说,就是对于若干个询问(A, B),sideman 想知道从顶点A 航行到顶点B 所经过的最危险的边的危险程度值最小可能是多少。作为sideman 的同学,你们要帮助sideman 返回家园,兼享受安全美妙的宇宙航行。所以这个任务就交给你了。

    输入输出格式

    输入格式:

    第一行包含两个正整数N 和M,表示点数和边数。

    之后 M 行,每行三个整数A,B 和L,表示顶点A 和B 之间有一条边长为L 的边。顶点从1 开始标号。

    下面一行包含一个正整数 Q,表示询问的数目。

    之后 Q 行,每行两个整数A 和B,表示询问A 和B 之间最危险的边危险程度的可能最小值。

    输出格式:

    对于每个询问, 在单独的一行内输出结果。如果两个顶点之间不可达, 输出impossible。

    货车运输。最小瓶颈路。

    code:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    const int wx=1000017;
    
    inline int read(){
    	int sum=0,f=1; char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0';ch=getchar();}
    	return sum*f;
    }
    
    int fa[wx],dep[wx];
    int f[wx][23],dis[wx][23];
    int head[wx];
    int n,m,num,q;
    
    struct node{
    	int l,r,d;
    	friend bool operator < (const node& a,const node& b){
    		return a.d<b.d;
    	}
    }a[wx*2];
    
    struct e{
    	int nxt,to,dis;
    }edge[wx*2];
    
    void add(int from,int to,int dis){
    	edge[++num].nxt=head[from];
    	edge[num].to=to;
    	edge[num].dis=dis;
    	head[from]=num;
    }
    
    int find(int x){
    	if(x==fa[x])return x;
    	return fa[x]=find(fa[x]);
    }
    
    void build(int flag){
    	add(a[flag].l,a[flag].r,a[flag].d);
    	add(a[flag].r,a[flag].l,a[flag].d);
    }
    
    void Kruskal(){
    	for(int i=1;i<=n;i++)fa[i]=i;
    	sort(a+1,a+1+m);
    	for(int i=1;i<=m;i++){
    		if(find(a[i].l)!=find(a[i].r)){
    			fa[find(a[i].l)]=find(a[i].r);
    			build(i);
    		}
    	}
    }
    
    void dfs(int u,int father){
    	dep[u]=dep[father]+1;
    	for(int i=head[u];i;i=edge[i].nxt){
    		int v=edge[i].to;
    		if(v==father)continue;
    		f[v][0]=u;
    		dis[v][0]=edge[i].dis;
    		dfs(v,u);
    	}
    }
    
    void pre(){
    	for(int j=1;j<=21;j++){
    		for(int i=1;i<=n;i++){
    			f[i][j]=f[f[i][j-1]][j-1];
    			dis[i][j]=max(dis[i][j-1],dis[f[i][j-1]][j-1]);
    		}
    	}
    }
    
    int FFF(int x,int y){
    	int re=0;
    	if(dep[x]<dep[y])swap(x,y);
    	for(int i=21;i>=0;i--){
    		if(dep[f[x][i]]>=dep[y]){
    			re=max(re,dis[x][i]);
    			x=f[x][i];
    		}
    	}
    	if(x==y)return re;
    	for(int i=21;i>=0;i--){
    		if(f[x][i]!=f[y][i]){
    			re=max(re,dis[x][i]);
    			re=max(re,dis[y][i]);
    			x=f[x][i]; y=f[y][i];
    		}
    	}
    	return max(re,max(dis[x][0],dis[y][0]));
    }
    
    int main(){
    	n=read(); m=read();
    	for(int i=1;i<=m;i++){
    		int x,y,z;
    		x=read(); y=read(); z=read();
    		a[i].l=x; a[i].r=y; a[i].d=z;
    	}
    	Kruskal();
    	dfs(1,0); pre();
    	q=read();
    	for(int i=1;i<=q;i++){
    		int x,y;
    		x=read(); y=read(); 
    		FFF(x,y);
    		if(find(x)==find(y)) printf("%d
    ",FFF(x,y));
    		else printf("impossible
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    Servlet介绍(一)
    iOS Dev (50)用代码实现图片加圆角
    Codeforces Round #265 (Div. 2) D. Restore Cube 立方体推断
    JVM:垃圾回收机制和调优手段
    Memcachedclient-XMemcached使用
    JVM中类的卸载机制
    血型统计
    iOS 事件传递及响应过程
    java 对象参数去空格方式
    spring aop 一个挡板例子
  • 原文地址:https://www.cnblogs.com/wangxiaodai/p/9792094.html
Copyright © 2011-2022 走看看