zoukankan      html  css  js  c++  java
  • 【luogu P2195 HXY造公园】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2195

    fir.吐槽题目(省略1w字

    sec.考虑对一个森林的维护,每棵树用并查集维护。
    操作1:输出当前查询点的树的直径
    操作2:对于两条直径连接起来最短,肯定是连两个中点(显而易见

    thi.小trick:重复利用vis数组—变成int,这样对于每棵树实际每个根不一样标号时的vis值也不同

    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn = 3 * 1e5 + 10;
    inline int read()
    {
        int k=0,f=1;
        char c=getchar();
        while(!isdigit(c))
        {
            if(c=='-')f=-1;
            c=getchar();
        }
        while(isdigit(c))
        {
            k=(k<<1)+(k<<3)+c-48;
            c=getchar();
        }
        return k*f;
    }
    struct edge{
    	int from, to, next, len;
    }e[maxn<<2];
    int cnt, head[maxn];
    int dis[maxn], node, path[maxn], n, m, Q, fa[maxn], ans, vis[maxn];
    void add(int u, int v, int w)
    {
    	e[++cnt].from = u;
    	e[cnt].to = v;
    	e[cnt].len = w;
    	e[cnt].next = head[u];
    	head[u] = cnt;
    }
    int find(int x)
    {
    	return fa[x] == x ? x : fa[x] = find(fa[x]);
    }
    
    int bfs(int s)
    {
    	queue<int> q;
    	vis[s] = s;
    	dis[s] = 0;
    	q.push(s);
    	int node, d = 0;
    	while(!q.empty())
    	{
    		int now = q.front(); q.pop();
    		for(int i = head[now]; i != -1; i = e[i].next)
    		{
    			if(vis[e[i].to] != s)
    			{
    				dis[e[i].to] = dis[now] + e[i].len;
    				vis[e[i].to] = s; 
    				q.push(e[i].to);
    				if(dis[node] < dis[e[i].to])
    				{
    					node = e[i].to;
    					d = dis[e[i].to];
    				}	
    			}
    		}
    	}
    	dis[node] = 0;
    	vis[node] = node;
    	q.push(node);
    	while(!q.empty())
    	{
    		int now = q.front(); q.pop();
    		for(int i = head[now]; i != -1; i = e[i].next)
    		{
    			if(vis[e[i].to] != node)
    			{
    				dis[e[i].to] = dis[now] + e[i].len;
    				vis[e[i].to] = node; 
    				q.push(e[i].to);
    				if(d < dis[e[i].to])
    				d = dis[e[i].to];
    			}
    		}
    	}
    	return d;
    }
    int main()
    {
    	memset(head, -1, sizeof(head));
    	n = read(); m = read(); Q = read();
    	for(int i = 1; i <= n; i++) fa[i] = i;
    	for(int i = 1; i <= m; i++)
    	{
    		int u, v;
    		u = read(); v = read();
    		add(u, v, 1), add(v, u, 1);
    		if(find(u) != find(v))
    		fa[find(u)] = find(v);
    	}
    	for(int i = 1; i <= n; i++)
    	{
    		if(i == find(i)) path[i] = bfs(i);
    	}
    	for(int i = 1; i <= Q; i++)
    	{
    		int opt, x, y;
    		opt = read();
    		if(opt == 1)
    		{
    			x = read();
    			printf("%d
    ", path[find(x)]);
    		}
    		else
    		{
    			x = read(); y = read(); 
    			int fx = find(x), fy = find(y);
    			if(fx != fy)
    			{
    				fa[fx] = fy;
    				path[fy] = max(max(path[fy], path[fx]), (path[fx]+1)/2 + (path[fy]+1)/2 + 1);
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    C语言函数手册—函数分类列表
    HTTP协议详解(一直在用可是这篇太好了转一下)
    Substance风格实例大全javaswing皮肤风格大全(原)
    Component creation must be done on Event Dispatch Thread错误解决方法
    用开源Look&Feel (Substance)写 漂亮的Swing应用程序
    Swift翻译之-关于Swift
    Swift翻译之-Swift语法入门 Swift语法介绍
    Swift语言简介+快速上手
    JDK各个版本的新特性jdk1.5-jdk8
    5个常用Java代码混淆器 助你保护你的代码
  • 原文地址:https://www.cnblogs.com/MisakaAzusa/p/9779280.html
Copyright © 2011-2022 走看看