ural Pilot Work Experience(dfs + bfs )
题意:航空公司有p名飞行员,n条航线,每条航线上都必须有两名飞行员完成,一名正驾驶员,一名副驾驶员,公司规定,正驾驶员的工作年龄要比副驾驶员的多一年,现在给出你n条航线上驾驶员的编号,但是不知道谁是正驾驶,谁是副驾驶,求出这个公司所有驾驶员工作年龄的最大差值,最大差值不得大于50,如果不能满足条件就输出-1 。
思路:建图,每条航线上的正副驾驶之间连线,如果这是一个连通图,这直接有bfs枚举每一个点为起点,然后判断是否成立。如果不是连通图,先用dfs标记一下每个点属于那个连通图,然后用bfs判断每个连通图是否满足条件,如果都满足,则最大差值为49 ,如不满足则输出-1 。
代码:

#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 ; }