ural Pilot Work Experience(dfs + bfs )

题意:航空公司有p名飞行员,n条航线,每条航线上都必须有两名飞行员完成,一名正驾驶员,一名副驾驶员,公司规定,正驾驶员的工作年龄要比副驾驶员的多一年,现在给出你n条航线上驾驶员的编号,但是不知道谁是正驾驶,谁是副驾驶,求出这个公司所有驾驶员工作年龄的最大差值,最大差值不得大于50,如果不能满足条件就输出-1 。

思路:建图,每条航线上的正副驾驶之间连线,如果这是一个连通图,这直接有bfs枚举每一个点为起点,然后判断是否成立。如果不是连通图,先用dfs标记一下每个点属于那个连通图,然后用bfs判断每个连通图是否满足条件,如果都满足,则最大差值为49 ,如不满足则输出-1 。

代码:

View Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <map>
#include <stack>
#include <math.h>
#include <vector>
#define  N 55
using namespace std ;

int mp[N][N] , d[N] , f[N] , num[N] , s[N] ;
int n , m , cnt ;
queue<int>q ;

void init()
{
    memset( mp , 0 , sizeof ( mp ));//连接矩阵
    memset( d , 0 , sizeof( d )) ;//标记每个点属于哪个连通图
    memset( f , 0 , sizeof ( f )) ;//在同一连通图中,每个点的位置
    memset( num , -1 , sizeof ( num )) ;//每个连通图中最大的差值
    memset( s , 0 , sizeof ( s )) ;//最大差值是由哪个点为起点得到的
    cnt = 0 ;
}

void dfs( int x , int id )
{
    d[x] = id ;
    for ( int i = 1 ; i <= m ; i++ )
    if ( mp[x][i] && !d[i] )
    dfs( i , id ) ;
    return ;
}

int bfs( int x , int id )
{
    int u , k , i ;
    while( !q.empty()) q.pop();
    f[x] = id ;
    k = id ;
    q.push( x ) ;

    while ( !q.empty())
    {
        u = q.front() ;
        q.pop();
        k = max( k , f[u] );
        for ( i = 1 ; i <= m ; i++ )
        {
            if ( mp[u][i] )
            {
                if ( f[i] )
                {
                    if( abs( f[i] - f[u] ) != 1 )
                    return -1 ;
                }
                else
                {
                    f[i] = f[u] + 1 ;
                    q.push( i ) ;
                }
            }
        }
    }
    return ( k - id ) ;
}

int main()
{
    int i , j , x , y , k ;

    while( scanf ( "%d%d" , &n , &m ) != EOF )
    {
        init() ;
        for ( i = 1 ; i <= n ; i++ )
        {
            scanf ( "%d%d" , &x , &y ) ;
            mp[x][y] = mp[y][x] = 1 ;
        }

        for ( i = 1 ; i <= m ; i++ )
        {
            if ( !d[i] )
            dfs( i , ++cnt ) ;
        }

        /*for ( i = 1 ; i <= m ; i++ )
        cout<<d[i]<<" ";
        cout<<endl ;*/
        //cout<<cnt<<endl ;
        for ( i = 1 ; i <= cnt ; i++ )
        {
            for ( j = 1 ; j <= m ; j++ )
            {
                if ( d[j] == i )
                {
                    memset( f , 0 , sizeof ( f )) ;
                    k = bfs( j , 1 ) ;
                    if ( k != -1 )
                    {
                        if ( k > num[i] )
                        {
                            num[i] = k ;
                            s[i] = j ;
                        }
                    }
                }
            }
        }

        int flag = true ;
        for ( i = 1 ; i <= cnt ; i++ )
        if ( num[i] == -1 )
        {
            flag = false ;
            break ;
        }

        if( !flag )
        {
            printf ( "-1\n" ) ;
        }
        else
        {
            memset( f , 0 , sizeof ( f )) ;
            if ( cnt == 1 )
            {
                printf ( "%d\n" , num[1] ) ;
                bfs( s[1] , 1 ) ;
            }
            else
            {
                printf ( "49\n" ) ;
                bfs( s[1] , 1 ) ;
                for ( i = 2 ; i <= cnt ; i++ )
                {
                    bfs( s[i] , 50 - num[i] ) ;
                }
            }
            for ( i = 1 ; i <= m ; i++ )
            {
                printf ( "%d" , f[i] ) ;
                if ( i != m )
                printf ( " " ) ;
            }
            printf ( "\n" ) ;
        }
    }
    return 0 ;
}
原文地址:https://www.cnblogs.com/misty1/p/2875997.html