• P4408 [NOI2003]逃学的小孩


    Link

    desprition

    给你一颗树,让你找出三个点, (A,B,C) 满足 (AB leq AC) 使得 (AB + BC) 的长度最大。

    并输出这个长度

    sloution

    树的直径加暴力枚举。

    首先,要是 (BC) 的距离最大,我们肯定要选树的直径,然后就确定了 (B,C) 是树的直径的两个端点,

    现在主要是怎么确定 (A) ,我们在求树的直径的时候,可以求出每个点到 (B,C) 这两点之间的距离 ,跑三遍 (bfs) 就行。

    之后再暴力枚举一下 (A) ,最后的答案就是 (max(直径 + min(d1[i],d2[i])))

    然后就做完了。具体证明的话不太会emmmm.

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    using namespace std;
    #define int long long
    const int N = 1e5+10;
    int n,m,tot,zhijing,ans,u,v,w,st,en;
    int head[N],d1[N],d2[N];
    struct node
    {
    	int to,net,w;
    }e[N<<1];
    inline int read()
    {
    	int s = 0,w = 1; char ch= getchar();
    	while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
    	return s * w;
    }
    void add(int x,int y,int w)
    {
    	e[++tot].to = y;
    	e[tot].w = w;
    	e[tot].net = head[x];
    	head[x] = tot;
    }
    void bfs(int x)
    {
    	for(int i = 1; i <= n; i++) d1[i] = -1;
    	queue<int> q;
    	q.push(x); d1[x] = 0;
    	while(!q.empty())
    	{
    		int t = q.front(); q.pop();
    		for(int i = head[t]; i; i = e[i].net)
    		{
    			int to = e[i].to;
    			if(d1[to] == -1)
    			{
    				d1[to] = d1[t] + e[i].w;
    				q.push(to);
    			}
    		}
    	}
    }
    void bfs2(int x)
    {
    	for(int i = 1; i <= n; i++) d2[i] = -1;
    	queue<int> q;
    	q.push(x); d2[x] = 0;
    	while(!q.empty())
    	{
    		int t = q.front(); q.pop();
    		for(int i = head[t]; i; i = e[i].net)
    		{
    			int to = e[i].to;
    			if(d2[to] == -1)
    			{
    				d2[to] = d2[t] + e[i].w;
    				q.push(to);
    			}
    		}
    	}
    }
    signed main()
    {
    	n = read(); m = read();
    	for(int i = 1; i <= n-1; i++)
    	{
    		u = read(); v = read(); w = read();
    		add(u,v,w); add(v,u,w);
    	}
    	bfs(1);
    	for(int i = 1; i <= n; i++)
    	{
    		if(d1[i] > d1[st]) st = i;
    	}
    	bfs(st);
    	for(int i = 1; i <= n; i++)
    	{
    		if(d1[i] > d1[en]) en = i;
    	}
    	zhijing = d1[en];
    	bfs2(en);
    	for(int i = 1; i <= n; i++)
    	{
    		ans = max(ans,min(d1[i],d2[i]));
    	}
    	printf("%lld
    ",zhijing+ans);
    	return 0;
    }
    
  • 相关阅读:
    导航控制器的出栈
    UIPickView的基本使用
    多控制器
    通过Xib加载控制器的View
    从StoryBoard加载控制器
    模仿UIApplication单例
    LaunchScreen原理
    UIWindow
    指定初始化的运用
    零长度数组在内核中的运用
  • 原文地址:https://www.cnblogs.com/genshy/p/13871865.html
Copyright © 2020-2023  润新知