LightOJ-1094 求树直径,水

LightOJ 1094

题意:给出一棵树求直径。

总结:搜两次即可。先任意找一个点为根找到离它最远的点,再以这个点为根找离它最远的距离。

// LightOJ-1094 
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<bitset>
#include<vector>
#include<set>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define F(i,a,b)  for (int i=a;i<b;i++)
#define FF(i,a,b) for (int i=a;i<=b;i++)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
typedef long long ll;
const int N = 1e5+10;

int T, cas, n, tot, dis[N], head[N], vis[N];
struct Edge { int to, next, w; }edge[N];

void Addedge(int u, int v, int w)
{
    edge[tot].to=v;
    edge[tot].w=w;
    edge[tot].next=head[u];
    head[u]=tot++;
}
void dfs(int u)
{
    vis[u]=1;
    for(int e=head[u]; e!=-1; e=edge[e].next) {
        int v=edge[e].to, w=edge[e].w;
        if(vis[v]==0) {
            dis[v]=dis[u]+w;
            dfs(v);
        }
    }
}
void Solve()
{
    dfs(0);
    int mi, maxn=-INF;
    FF(i,0,n-1) if(maxn<dis[i]) maxn=dis[i], mi=i;
    mes(dis, 0);  mes(vis, 0);
    dfs(mi);
    FF(i,0,n-1) if(maxn<dis[i]) maxn=dis[i], mi=i;
    printf("Case %d: %d
", cas, maxn);
}
int main()
{
    scanf("%d", &T);
    for(cas=1; cas<=T; cas++) {
        tot=0;  mes(vis, 0);  mes(dis, 0);  mes(head, -1);
        scanf("%d", &n);
        FF(i,1,n-1) {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            Addedge(u, v, w);
            Addedge(v, u, w);
        }
        Solve();
    }

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/sbfhy/p/6349942.html