zoukankan      html  css  js  c++  java
  • 【洛谷P2245】星际导航

    题面

    题解

    (kruskal)重构树板子题??(大雾

    因为重构树上两点之间的(LCA)的权值就是原图上最小生成树上的瓶颈。

    所以建个重构树,跑(LCA)即可。

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define RG register
    #define file(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
    
    inline int read()
    {
    	int data = 0, w = 1;
    	char ch = getchar();
    	while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    	if(ch == '-') w = -1, ch = getchar();
    	while(ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
    	return data * w;
    }
    
    const int maxn(2e5 + 10), maxm(3e5 + 10);
    struct edge { int next, to; } e[maxn << 2];
    struct Edge { int from, to, dis; } E[maxm];
    
    inline bool cmp(const Edge &lhs, const Edge &rhs) { return lhs.dis < rhs.dis; }
    int fa[maxn], f[maxn], size[maxn], belong[maxn], heavy[maxn], head[maxn], e_num, cnt, pos[maxn], val[maxn], n, m, n_cnt;
    inline void add_edge(int from, int to) { e[++e_num] = (edge) {head[from], to}; head[from] = e_num; }
    
    void dfs(int x)
    {
    	size[x] = 1;
    	for(RG int i = head[x]; i; i = e[i].next)
    	{
    		int to = e[i].to; if(to == fa[x]) continue;
    		fa[to] = x; dfs(to); size[x] += size[to];
    		if(size[heavy[x]] < size[to]) heavy[x] = to;
    	}
    }
    
    void dfs(int x, int chain)
    {
    	pos[x] = ++cnt; belong[x] = chain;
    	if(!heavy[x]) return;
    	dfs(heavy[x], chain);
    	for(RG int i = head[x]; i; i = e[i].next)
    	{
    		int to = e[i].to; if(to == fa[x] || to == heavy[x]) continue;
    		dfs(to, to);
    	}
    }
    
    inline int LCA(int a, int b)
    {
    	while(belong[a] != belong[b])
    	{
    		if(pos[belong[a]] < pos[belong[b]]) std::swap(a, b);
    		a = fa[belong[a]];
    	}
    	return pos[a] < pos[b] ? a : b;
    }
    
    inline int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }
    inline void Kruskal()
    {
    	std::sort(E + 1, E + m + 1, cmp); n_cnt = n;
    	for(RG int i = 1; i <= m; i++)
    	{
    		int fx = find(E[i].from), fy = find(E[i].to);
    		if(fx == fy) continue;
    		f[fx] = f[fy] = ++n_cnt; f[n_cnt] = n_cnt;
    		add_edge(n_cnt, fx); add_edge(fx, n_cnt);
    		add_edge(n_cnt, fy); add_edge(fy, n_cnt);
    		val[n_cnt] = E[i].dis;
    	}
    
    	for(RG int i = n_cnt; i; i--)
    		if(!pos[i]) dfs(i), dfs(i, i);
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
    	file(cpp);
    #endif
    	n = read(); m = read();
    	for(RG int i = 1; i <= m; i++) E[i] = (Edge) {read(), read(), read()};
    	for(RG int i = 1; i <= n; i++) f[i] = i;
    	RG int q = read(); Kruskal();
    	while(q--)
    	{
    		int a = read(), b = read();
    		if(find(a) != find(b)) puts("impossible");
    		else printf("%d
    ", val[LCA(a, b)]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    【算法】LeetCode算法题-Count And Say
    【算法】LeetCode算法题-Search Insert Position
    使用POI设置excel背景色
    Ubuntu中开启MySQL远程访问功能,并将另一个数据库服务器中的数据迁移到新的服务器中
    利用mybatis_generator自动生成Dao、Model、Mapping相关文件
    Meven笔记
    js调用百度地图API创建地图
    MySQL中日期与字符串相互转换,并进行日期比较查询
    java中将汉字转换成16进制
    Java中将16进制字符串转换成汉字
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/9884496.html
Copyright © 2011-2022 走看看