zoukankan      html  css  js  c++  java
  • P2245 星际导航 瓶颈路

    (color{#0066ff}{ 题目描述 })

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

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

    (color{#0066ff}{输入格式})

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

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

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

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

    (color{#0066ff}{输出格式})

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

    (color{#0066ff}{输入样例})

    4 5
    1 2 5
    1 3 2
    2 3 11
    2 4 6
    3 4 4
    3
    2 3
    1 4
    1 2
    

    (color{#0066ff}{输出样例})

    5
    4
    5
    

    (color{#0066ff}{数据范围与提示})

    对于 (40\%) 的数据,满足 (N leq 1000, M leq 3000, Q leq 1000)

    对于 (80\%) 的数据,满足 (N leq 10000, M leq 10^5, Q leq 1000)

    对于 $100%$100% 的数据,满足 (N leq 10^5, M leq 3 imes 10^5, Q leq 10^5, L leq 10^9)。数据不保证没有重边和自环。

    (color{#0066ff}{ 题解 })

    一个无向图,看到最大边最小,我去,最小生成树。。。

    然后神奇的发现,题目不保证没有重边自环的问题就解决了

    于是我们就得到了一个森林

    每次询问两个点,如果不在一棵树中(通过最小生成树的ufs判断)输出无解

    否则输出其路径上最大边边权,显然倍增搞一下就行了

    #include<bits/stdc++.h>
    #define LL long long
    LL in() {
    	char ch; LL x = 0, f = 1;
    	while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
    	for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
    	return x * f;
    }
    int n, m;
    const int maxn = 1e5 + 10;
    struct node {
    	int to, dis;
    	node *nxt;
    	node(int to = 0, int dis = 0, node *nxt = NULL): to(to), dis(dis), nxt(nxt) {}
    	void *operator new(size_t) {
    		static node *S = NULL, *T = NULL;
    		return (S == T) && (T = (S = new node[1024]) + 1024), S++;
    	}
    }*head[maxn];
    bool vis[maxn];
    int dep[maxn];
    struct E {
    	int x, y, dis;
    	friend bool operator < (const E &a, const E &b) {
    		return a.dis < b.dis;
    	}
    }e[maxn << 2];
    int f[maxn][25], max[maxn][25];
    int b[maxn];
    void add(int from, int to, int dis) {
    	head[from] = new node(to, dis, head[from]);
    }
    int findset(int x) { return x == b[x]? b[x] : b[x] = findset(b[x]); }
    void Kruskal() {
    	for(int i = 1; i <= n; i++) b[i] = i;
    	for(int i = 1; i <= m; i++) e[i].x = in(), e[i].y = in(), e[i].dis = in();
    	std::sort(e + 1, e + m + 1);
    	for(int i = 1; i <= m; i++) {
    		int xx = findset(e[i].x);
    		int yy = findset(e[i].y);
    		if(xx != yy) {
    			b[xx] = yy;
    			add(e[i].x, e[i].y, e[i].dis);
    			add(e[i].y, e[i].x, e[i].dis);
    		}
    	}
    }
    void dfs(int x, int fa) {
    	vis[x] = true;
    	dep[x] = dep[fa] + 1;
    	f[x][0] = fa;
    	for(node *i = head[x]; i; i = i->nxt) {
    		if(i->to == fa) continue;
    		max[i->to][0] = i->dis;
    		dfs(i->to, x);
    	}
    }
    void beizeng() {
    	for(int i = 1; i <= n; i++) if(!vis[i]) dfs(i, 0);
    	for(int j = 1; j <= 24; j++)
    		for(int i = 1; i <= n; i++) {
    			f[i][j] = f[f[i][j - 1]][j - 1];
    			max[i][j] = std::max(max[i][j - 1], max[f[i][j - 1]][j - 1]);
    		}
    }
    int LCA(int x, int y) {
    	int dis = 0;
    	if(dep[x] < dep[y]) std::swap(x, y);
    	for(int i = 24; i >= 0; i--) 
    		if(dep[f[x][i]] >= dep[y]) 
    			dis = std::max(dis, max[x][i]), x = f[x][i];
    	if(x == y) return dis;
    	for(int i = 24; i >= 0; i--) 
    		if(f[x][i] != f[y][i]) {
    			dis = std::max(dis, std::max(max[x][i], max[y][i]));
    			x = f[x][i], y = f[y][i];
    		}
    	return std::max(dis, std::max(max[x][0], max[y][0]));
    }
    
    void query() {
    	int x, y;
    	for(int T = in(); T --> 0;) {
    		x = in(), y = in();
    		if(findset(x) != findset(y)) printf("impossible
    ");
    		else printf("%d
    ", LCA(x, y));
    	}
    }
    
    int main() {
    	n = in(), m = in();
    	Kruskal();
    	beizeng();
    	query();
    	return 0;
    }
    
  • 相关阅读:
    Django 模版当中使用中文 UnicodeDecodeError at / 问题
    sql中索引不会被用到的几种情况
    Django安装
    分享一个webapi接口性能测试的工具
    orleans 2.0 进阶之自定义持久化储存
    centos7 .net core 使用supervisor守护进程,可以后台运行
    将.net core 发布到Linux上的一些坑
    .net core 部署在Linux系统上运行的环境搭建总结
    .net core 基于NPOI 的excel导入导出类,支持自定义导出哪些字段,和判断导入是否有失败的记录
    基于Ace Admin 的菜单栏实现
  • 原文地址:https://www.cnblogs.com/olinr/p/10357534.html
Copyright © 2011-2022 走看看