首页 > 代码库 > 任务安排

任务安排

给定N(<=300)个人和N台机器,以及每个人操作某台机器的收益。请计算所有人都工作的情况下,最大的收益和。
输入:
第一行两个数分别表示人和机器的数量(两数相等)
接下来若干行,每行三个数,a,b,c表示a 操作机器b的收益为c.
输出:
两个数。(第一个数表示参加工作的人数(此数为N),第二个数表示最大收益和。)
样例:
输入:
3 3
1 2 10
1 1 9
1 3 3
2 1 10
2 2 9
2 3 3
3 1 8
3 2 9
3 3 8
输出:
3 28

最大费用流的话就是搞成负的再求最小费用流,也是很裸的题 。

  1 #include <iostream>  2 #include <cstdlib>  3 #include <cstdio>  4 #include <cstring>  5 #include <queue>  6 const int inf = 1 << 30 , maxn = 600 + 11 ;//1061109567  7 using namespace std ;  8 int n , val[maxn][maxn] , vol[maxn][maxn] , dis[maxn] , mark[maxn] , ans , s , t ;  9 queue< int > Q; 10  11 inline void Init(  ) 12 { 13     freopen( "NSOOJ#10400.in" , "r" , stdin ) ; 14     freopen( "NSOOJ#10400.out" , "w" , stdout ) ; 15 } 16  17 void add( int u , int v , int va , int vo ) 18 { 19     val[u][v] = va , vol[u][v] = vo ; 20 } 21  22  23 void input( ) 24 { 25     scanf( "%d" , &n ) ; scanf( "%d" , &n ) ; 26     int a , b ,c ; s = 0 , t = (n<<1) + 2 ; 27     while( ~scanf( "%d%d%d" , &a , &b , &c ) ) 28     { 29 //        cout<<a<<" "<<b<<" "<<c<<endl; 30         add( a , b+n , inf , -c ) ; 31         add( b+n , a , 0 , c ) ;   32     } 33     for( int x = 1 ; x <= n ; ++x ) 34     { 35         add( s , x , 1 , 0 ) ; 36         add( x , s , 0 , 0 ) ; 37     } 38     for( int x = 1 ; x <= n; ++x ) 39     { 40         add( x+n , t-1 , 1 , 0 ) ; 41         add( t-1 , x+n , 0 , 0 ) ; 42     } 43     add( t-1 , t , n , 0 ) ; 44     add( t , t-1 , 0 , 0 ) ; 45 } 46  47  48 bool spfa(  ) 49 { 50     memset( mark , 0 , sizeof(mark) ) ; 51     memset( dis , 127/2 , sizeof(dis) ) ; 52     mark[t] = 1 , dis[t] = 0 ; Q.push( t ) ; 53     while( !Q.empty( ) ) 54     { 55         int u = Q.front( ) ; Q.pop( ) ; 56         for( int i = 0 ; i <= t ; i++ ) 57         { 58             if( val[i][u]  && dis[i] > dis[u] + vol[i][u] ) 59             { 60                 dis[i] = dis[u] + vol[i][u] ; 61                 if( !mark[i] ) 62                 { 63                     Q.push( i ) ; 64                     mark[i] = true ; 65                 } 66             } 67         }  68         mark[u] = false ; 69     } 70     return dis[s] != 1061109567 ; 71 } 72  73  74 int dfs( int u , int f ) 75 { 76     mark[u] = 1 ; 77     if( u == t ) return f ; 78     int w , used = 0 ; 79     for( int v = 0 ; v <= t ; ++v ) 80     { 81         if( dis[v] == dis[u] - vol[u][v] && val[u][v]  && !mark[v] ) 82         { 83             w = f - used ; 84             w = dfs( v , min( w , val[u][v] ) ) ; 85             val[u][v] -= w , val[v][u] += w , used += w ; 86             ans += w * vol[u][v] ; 87             if( used == f ) return used ;  88         } 89     } 90     return used ; 91 } 92  93  94 void zkw( ) 95 { 96     int sum = 0 ; 97     while( spfa( ) ) 98     { 99         mark[t] = 1 ;100         while( mark[t] )101         {102             memset( mark , 0 , sizeof(mark) ) ;103             sum += dfs( s , inf ) ;104         }105     106     }107     printf( "%d %d\n" , sum , 0-ans ) ;108 }109 110 111 112 int main( )113 {114 //    Init(  ) ;115     input( ) ;116     zkw( ) ;117 //    fclose( stdin ) ;118 //    fclose( stdout ) ;119     return 0 ;120 }

 

任务安排