zoukankan      html  css  js  c++  java
  • 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 ;
    }
  • 相关阅读:
    Codevs 2296 仪仗队 2008年省队选拔赛山东
    Codevs 1535 封锁阳光大学
    Codevs 1069 关押罪犯 2010年NOIP全国联赛提高组
    Codevs 1218 疫情控制 2012年NOIP全国联赛提高组
    Codevs 1684 垃圾陷阱
    洛谷 P1108 低价购买
    Vijos P1325桐桐的糖果计划
    Codevs 3289 花匠 2013年NOIP全国联赛提高组
    Codevs 2611 观光旅游(floyed最小环)
    C语言基础之彩色版C语言(内含linux)
  • 原文地址:https://www.cnblogs.com/misty1/p/2875997.html
Copyright © 2011-2022 走看看