樹的直徑 | 簡答的兩道模板題

Farthest Nodes in a Tree

Given a tree (a connected graph with no cycles), you have to find the farthest nodes in the tree. The edges of the tree are weighted and undirected. That means you have to find two nodes in the tree whose distance is maximum amongst all nodes.node

Input
starts with an integer T (≤ 10), denoting the number of test cases. Each case starts with an integer n (2 ≤ n ≤ 30000) denoting the total number of nodes in the tree. The nodes are numbered from 0 to n-1. Each of the next n-1 lines will contain three integers u v w (0 ≤ u, v < n, u ≠ v, 1 ≤ w ≤ 10000) denoting that node u and v are connected by an edge whose weight is w. You can assume that the input will form a valid tree.ios

Output網絡

For each case, print the case number and the maximum distance.測試

Sample Inputspa

2
    4
    0 1 20
    1 2 30
    2 3 50
    5
    0 2 20
    2 1 10
    0 3 29
    0 4 50

Sample Outputcode

Case 1: 100
    Case 2: 80

這個題剛開始一直不理解(這道題是第一次接觸樹的直徑),可後來看看了看學長給我板子。我去咋這麼簡單emmm。只要從任意一個節點出發而後找到距離他最遠的節點,而後再讓這個最遠的出發去找距離這個最遠的,這兩個節點的距離就是樹的直徑!
這就是一個簡單的板子題orm

#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
typedef pair<int,int> pa;

bool flag[100100];
int step[100100];
vector<pa>v[100100];
int a,b,c,sum;
int t,n;

int dfs(int x)
{
    sum=0;
    memset(flag,0,sizeof flag);
    memset(step,0,sizeof step);
    queue<int>q;
    q.push(x);
    flag[x]=1;
    int yy=0;
    while(!q.empty() )
    {
        int xx=q.front() ;
        q.pop() ;
        if(step[xx]>sum)
        {
            sum=step[xx];
            yy=xx;
        }
        pa p;
        for(int i=0;i<v[xx].size() ;i++)
        {
            p=v[xx][i];
            int y=p.first ;
            if(!flag[y])
            {
                flag[y]=1;
                step[y]=step[xx]+p.second;
                q.push(y);
            }
        }
    }
    return yy;
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>t;

        for(int i=1;i<=t;i++)
        {
            cin>>n;
            for(int k=0;k<n;k++) 
                v[k].clear() ;
            for(int j=1;j<n;j++)
            {
                cin>>a>>b>>c;
                v[a].push_back(make_pair(b,c));//雙向存儲便於查找
                 v[b].push_back(make_pair(a,c));     
            }
            dfs(dfs(0));
            cout<<"Case "<<i<<": "<<sum<<endl;
        }

    return 0;
}

E-Computer

描述
一所學校不久前買了第一臺電腦(因此這臺電腦的ID是1)。近年來,學校購買了N-1新電腦。每臺新電腦都鏈接到一臺先前安裝的電腦上。學校的管理人員擔憂網絡運行緩慢,但願知道第i臺計算機須要發送信號的最大距離si(即到最遠計算機的電纜長度)。您須要提供此信息。blog

提示:示例輸入與此圖對應。從圖中,你能夠看到計算機4離1最遠,因此s1=3。計算機4和5是距離2最遠的,因此s2=2。計算機5是離3最遠的,因此s3=3。咱們也獲得了s4=4,s5=4。three

輸入
輸入文件包含多組測試樣例。在每組樣例中,第一行中都有天然數n(n<=10000),而後是(n-1)行,其中包含對計算機的描述。第i行包含兩個天然數-第i計算機所鏈接的計算機和用於鏈接的電纜長度。電纜總長度不超過10^9。輸入行中的數字用空格分隔。ci

輸出
對於每組樣例,輸出n行。第i行第i臺計算機的到其餘計算機的最大長度Si(1<=i<=n)。

樣例輸入

5
    1 1
    2 1
    3 1
    1 1

樣例輸出

3
    2
    3
    4
    4

提示
示例輸入與此圖對應。從圖中,你能夠看到計算機4離1最遠,因此s1=3。計算機4和5是距離2最遠的,因此s2=2。計算機5是離3最遠的,因此s3=3。咱們也獲得了s4=4,s5=4。

從一個點出發尋找到距離它最遠的點,而後在從這個點出發尋找距離它最遠的點中間記錄每一個節點的最遠路程,這樣算的的路徑都是距離該節點的最遠路徑,而後再從距離這個點的最遠的點在進行dfs還更新節點距離,那麼最後的結果就是了

#include<iostream>
#include<algorithm> 
#include<iostream>
#include<cstring>
#include<vector>

using namespace std;

typedef pair<int,int> pa;
int n,maxlen,s;
vector<pa>v[100100];
int dp[100100];

int dfs(int x,int y,int l)
{
    if(maxlen<=l)
    {
        maxlen=l;
        s=x;
    }
    pa p;
    for(int i=0;i<v[x].size() ;i++)
    {
        p=v[x][i];
        if(p.first ==y) continue;
        else
        {    
            dfs(p.first ,x,l+p.second);
            dp[p.first]=max(dp[p.first],l+p.second);
        }
    }
}

int main()
{
    while(cin>>n)
    {
        int x,y;
        memset(dp,0,sizeof dp);
        for(int i=0;i<=n;i++) v[i].clear() ;
        for(int  i=2;i<=n;i++)
        {
            cin>>x>>y;
            v[x].push_back(make_pair(i,y));
            v[i].push_back(make_pair(x,y));  
        }
        s=0;
        maxlen=0;
        maxlen=0;
        dfs(1,-1,0);
        dfs(s,-1,0);
        dfs(s,-1,0);
        for(int i=1;i<=n;i++) cout<<dp[i]<<endl;
    }
    return 0;
}
相關文章
相關標籤/搜索