UVa 259 Software Allocation ( 最大流 )

这道题也是,输入很坑,每组之间也空格结束,最后以EOF结束

建图其实有一种比这个好的方法,不用拆点,就是源点和computer相连,容量1, computer和program连,容量1, program和汇点连,容量为相应数字

但是一下代码,是拆点做的,把computer拆了,因为computer的容量为1,下面代码也是对照这个建图方法建的,program和源点连,容量为相应数字,和computer连,容量为1,computer容量为1, computer拆出来的点,和汇点连,容量INF

代码如下:

//by Molly
//Maximum Flow
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
//标号0为超级源点,标号1-26为26中应用程序,27-46(因为每个computer每天只能做一个程序,所以为computer是有容量的,要拆成两个点)computer的编号,48为超级汇点
const int INF = 1000000;
const int N = 100;
int cap[N][N], flow[N][N], a[N], p[N];
int s, t, sum;
char ap, num, com[N], ans[15];
bool maxFlow() {
    queue  q;
    memset(flow, 0, sizeof(flow));
    int f = 0;
    while ( 1 ) {
        for ( int i = 0; i <= t; p[i++] = -1 );
        memset(a, 0, sizeof(a));
        a[s] = INF;
        q.push(s);
        while ( !q.empty() ) {
            int u = q.front(); q.pop();
            for ( int v = 0; v <= t; ++v ) {
                if ( !a[v] && cap[u][v] > flow[u][v] ) {
                    p[v] = u;
                    q.push(v);
                    a[v] = min( a[u], cap[u][v] - flow[u][v] );
                }
            }
        }
        if ( a[t] == 0 ) break;
        for ( int u = t; u != s; u = p[u] ) {
            if ( u < 37 && u > 26 ) if ( p[u] != -1 ) ans[u-27] = p[u] + 'A' - 1;
            flow[p[u]][u] += a[t];
            flow[u][p[u]] -= a[t];
        }
        f += a[t];
    }
    if ( f >= sum ) return true;
    else return false;
}
void build () {
    int u = ap-'A'+1, c = num-'0';
    cap[s][u] += c;
    for ( int v = 0; com[v] != ';'&& v < strlen(com); ++v ){ 
        cap[u][com[v]-'0'+27] += 1; 
    }
}
void init() {
    for ( int i = 27; i < 37; ++i ) {
        cap[i][i+10] += 1; cap[i+10][t] += INF;
    }
} 

int main()
{
// freopen("input.txt","r", stdin);
// freopen("output.txt", "w", stdout); 
    while ( cin >> ap >> num >> com ) {
        memset(cap, 0, sizeof(cap));
        getchar();
        build();
        s = 0, t = 47, sum = num-'0';
        init();
        while ( ( ap = getchar() ) != 0xa && ap != EOF ) {
            scanf("%c %s", &num, com);
            getchar();
            sum += num - '0';
            build();
        }
        for ( int i = 0; i < 10; ans[i++] = '_' );
        if ( !maxFlow() ) cout << "!" << endl;
        else {
            for ( int i = 0; i < 10; ++i ) 
               cout << ans[i];
            cout << endl;
        }
        //for ( int i = 0; i <= t; printf("\n"), ++i ) 
          //  for ( int j = 0; j <= t; ++j ) printf("%d ", cap[i][j] );
    }
} 



你可能感兴趣的:(网络流)