• 洛谷P4408 逃学的小孩


    题目

    求树的直径,因为任意两个居住点之间有且只有一条通路,所以这是一棵树。

    根据题意父母先从C去A,再去B,或者反过来。

    我们一定是要让A到B最大,也要让C到A和B的最小值最大。

    AB最大一定就是直径了。

    CA最大直接先求出任意一条直径的两个端点,必定一个是A、一个是B。然后枚举C,找到最大的(min(CA,CB))然后与AB相加即可。

    #include <bits/stdc++.h>
    #define int long long  
    #define N 1010011
    using namespace std;
    struct edg {				
    	int from, to, nex, len;// vis表示是否在最大生成树上 
    }e[N * 2];		
    int n, m, cnt, ans, ansk, lin[N], dis1[N], vis[N];// 这必是一颗树
    int disk[N];
    inline void add(int f, int t, int c)
    {
    	e[++cnt].nex = lin[f];
    	e[cnt].to = t;
    	e[cnt].len = c;
    	lin[f] = cnt;
    }
    void dfs(int now)
    {
    	vis[now] = 1;
    	for (int i = lin[now]; i; i = e[i].nex)
    	{
    		int to = e[i].to;
    		if (!vis[to])
    		{
    			dis1[to] = dis1[now] + e[i].len;
    			ans = max(ans, dis1[to]);
    			dfs(to);
    		}			
    	}
    }
    void dfs2(int now)
    {
    	vis[now] = 1;
    	for (int i = lin[now]; i; i = e[i].nex)
    	{
    		int to = e[i].to;
    		if (!vis[to])
    		{
    			disk[to] = disk[now] + e[i].len;
    			if (disk[to] > ans)
    			 	ans = max(ans, disk[to]), ansk = to;
    			dfs2(to);
    		}			
    	}
    }
    signed main()
    {
    	scanf("%lld%lld", &n, &m);
    	for (int i = 1, a, b, c; i <= m; i++)
    	{
    		scanf("%lld%lld%lld", &a, &b, &c);
    		add(a, b, c);
    		add(b, a, c);
    	}
    	dfs(1);
    	int maxn = 0, maxk = 0;	
    	for (int i = 2; i <= n; i++)
    	{
     		if (dis1[i] > maxn)
     		{
    			maxn = dis1[i];
    			maxk = i;
     		} 
    	}
     	ans = 0; 
     	maxn = 0;
    	memset(vis, 0, sizeof(vis));
     	dfs2(maxk);
    	memset(vis, 0, sizeof(vis));
     	memset(dis1, 0, sizeof(dis1));
     	dfs(ansk);
     	for (int i = 1; i <= n; i++)
     	{
     		if (i == maxk || i == ansk) continue;
     		maxn = max(maxn, min(dis1[i], disk[i]));
     	}
     	printf("%lld", maxn + ans);//ans是树的直径大小。
    }
    
    /*
    4 3
    1 2 1
    1 3 1
    1 4 2
    5
    */
    
  • 相关阅读:
    Linux性能评测工具之一:gprof篇
    几个源码下载的网站
    linux svn代码回滚命令
    这就是阶层——你根本不知道世界有多残酷
    shell脚本中的数据传递方式
    XGBoost参数调优完全指南(附Python代码)
    机器学习(一) ---- 最优化理论基础
    Docker构建Java web应用服务
    使用Dockerfile创建支持SSH服务的镜像
    使用commit方式构建具有sshd服务的centos镜像
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/11728214.html
Copyright © 2020-2023  润新知