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 ;
    }
  • 相关阅读:
    洛谷 1498 南蛮图腾——模拟
    bzoj 4198 [Noi2015]荷马史诗——哈夫曼树
    bzoj 1026 [SCOI2009]windy数——数位dp水题
    bzoj 1045 [HAOI2008] 糖果传递——设变量推式子
    bzoj 4521 [Cqoi2016]手机号码——数位dp
    bzoj1044 [HAOI2008]木棍分割——前缀和优化DP
    bzoj1090 [SCOI2003]字符串折叠——区间DP
    bzoj1911 [Apio2010]特别行动队——斜率优化DP
    bzoj1025 [SCOI2009]游戏——因数DP
    bzoj1207 [HNOI2004]打鼹鼠——LIS
  • 原文地址:https://www.cnblogs.com/misty1/p/2875997.html
Copyright © 2011-2022 走看看