zoukankan      html  css  js  c++  java
  • 洛谷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
    */
    
  • 相关阅读:
    5.9编程练习
    linux下查看torch版本和cuda版本
    4.13编程练习
    C++ Primer Plus-3.7编程练习-第2题和第5题
    More on vim tips
    Method Calling in Perl
    换零钱 动态规划解法 C语言描述
    海伦平方根算法(LISP描述)
    expect 实现模拟交互
    tmux 入门
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/11728214.html
Copyright © 2011-2022 走看看