【二叉树】2392:Clear Cold Water

本文介绍了一道USACO Bronze级别的编程题,题目要求找出从奶牛场到各分支点最短路径的距离。提供了两种解题思路,一种是先序遍历填充距离数组,另一种是使用BFS遍历。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2392:Clear Cold Water

总时间限制: 
10000ms
单个测试点时间限制: 
1000ms
内存限制: 
65536kB
描述
The steamy, sweltering summers of Wisconsin's dairy district stimulate the cows to slake their thirst. Farmer John pipes clear cold water into a set of N (3 <= N <= 99999; N odd) branching pipes conveniently numbered 1..N from a pump located at the barn. As the water flows through the pipes, the summer heat warms it. Bessie wants to find the coldest water so she can enjoy the weather more than any other cow.

She has mapped the entire set of branching pipes and noted that they form a tree with its root at the farm and furthermore that every branch point has exactly two pipes exiting from it. Surprisingly, every pipe is exactly one unit in length; of course, all N pipes connect up in one way or another to the pipe-tree.

Given the map of all the pipe connctions, make a list of the distance from the barn for every branching point and endpoint.Bessie will use the list to find the very coldest water.

The endpoint of a pipe, which might enter a branching point or might be a spigot, is named by the pipe's number. The map contains C (1 <= C <= N) connections, each of which specifies three integers: the endpoint E_i (1 <= E_i <= N) of a pipe and two branching pipes B1_i and B2_i (2 <= B1_i <= N; 2 <= B2_i <= N). Pipe number 1 connects to the barn; the distance from its endpoint to the barn is 1.
输入
* Line 1: Two space-separated integers: N and C

* Lines 2..C+1: Line i+1 describes branching point i with three space-separated integers: E_i, B1_i, and B2_i
输出
* Lines 1..N: Line i of the output contains a single integer that is the distance from the barn to the endpoint of pipe i
样例输入
5 2
3 5 4
1 2 3
样例输出
1
2
2
3
3
提示
INPUT DETAILS:

The input above describes this pipe map:
                    +------+
                    | Barn |
                    +------+
                       | 1
                       *
                    2 / \ 3
                         *
                      4 / \ 5


OUTPUT DETAILS:

Pipe 1 is always distance 1 from the barn. Pipes 2 and 3 connect directly to pipe 1 and thus are distance 2 from the barn. Pipes 4 and 5, which connect to pipe 3, are distance 3 from the barn.
来源
USACO Open 2008 Bronze

注意这个oj上的评测是有毒的。0.0
这个题,可以使用先根遍历填充dis数组,或者bfs遍历。
dfs方法,参考标程:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#define MAX 100000
using namespace std;
int v[MAX][2];
int vis[MAX];
int N,C;
void dfs(int x){
	for(int i=0;i<2;i++){
		if(v[x][i]!=0&&vis[v[x][i]]==0){
			//有子树并且没有遍历过
			vis[v[x][i]]=vis[x]+1;
			dfs(v[x][i]);
		}
	}
}

int main(){
	scanf("%d%d",&N,&C);
	for(int i=0;i<=N;i++){
		v[i][0]=v[i][1]=0;
	}
	for(int i=0;i<C;i++){
		int x,a,b;
		scanf("%d%d%d",&x,&a,&b);
		v[x][0]=a;
		v[x][1]=b;
	}
	vis[1]=1;
	dfs(1);
	for(int i=1;i<=N;i++){
		printf("%d\n",vis[i]);
	}
}
bfs方法,转自https://www.cnblogs.com/Ateisti/p/6033185.html
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
const int N = 100000 + 11 ;
using namespace std ;
int n , m , dis[N] ;
bool used[N] ;
struct id
{
    int l , r ;
} links[N] ;

void Init( )
{
    scanf( "%d%d" , &n , &m ) ; int a , b , c ;
    for( int x = 1 ; x <= m ; ++x )
    {
        scanf( "%d%d%d" , &a , &b , &c ) ;
        links[a].l = b , links[a].r = c ;
    }
}


queue< int > Q ; 
void Solve( )
{
    memset( dis , 127/2 , sizeof( dis ) ) ;
    dis[1] = 1 ; Q.push( 1 ) ; used[1] = 1 ;
    while( !Q.empty( ) )
    {
        int u = Q.front( ) ; Q.pop( ) ;
        int l = links[u].l ;
        if( dis[l] > dis[u] + 1 )
        {
            dis[l] = dis[u] + 1 ;
            if( ! used[l] )
            {
                used[l] = true ;
                Q.push( l ) ;
            }
        }
        int r = links[u].r ;
        if( dis[r] > dis[u] + 1 )
        {
            dis[r] = dis[u] + 1 ;
            if( !used[r] )
            {
                used[r] = true ;
                Q.push( r ) ;
            }
        }
    }
}

void Output( )
{
    for( int x = 1 ; x <= n ; ++x )
        printf( "%d\n" , dis[x] ) ;
}


int main( )
{
    freopen( "2359.in" , "r" , stdin ) ;
    freopen( "2359.out" , "w" , stdout ) ;
    Init( ) ;
    Solve( ) ;
    Output( ) ;
    fclose( stdin ) ;
    fclose( stdout ) ;
    return 0 ;
}

总得来说,先序遍历的思路更清楚,因为下一层距离是本层的距离+1,那么一直遍历下去就可以了。
bfs练习使用队列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值