程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 4292 Food(拆點,最大流)

HDU 4292 Food(拆點,最大流)

編輯:C++入門知識

[cpp] 
/*
最大流問題
拆點:增加超級源點和匯點,源點於食物相連,邊的權值為食物最大量;飲料與匯點相連,變得權值為飲料的最大量;
將人拆分成兩個,一個與食物相連,一個與飲料相連,權值可以為1也可以為INF,無影響。
將拆分後的兩個節點相連,邊的權值為1
*/ 
 
#include <cstdio> 
#include <cstring> 
const int nMax = 2007; 
const int INF = 0x3fffffff; 
int N, F, D; 
int NN; 
struct Adj 

    int v, w; 
    int next; 
    Adj(){} 
    Adj(int v, int w, int next):v(v), w(w), next(next){} 
}adj[100 * nMax]; 
int head[nMax]; 
int cnt; 
int dis[nMax], num[nMax]; 
 
void addEdge(int u, int v, int w) 

    adj[cnt] = Adj(v, w, head[u]); 
    head[u] = cnt ++; 
    adj[cnt] = Adj(u, 0, head[v]); 
    head[v] = cnt ++; 

 
int min(int a, int b) 

    return a < b ? a : b; 

 
int dfs(int u, int s, int d, int cost) 

    if(u == d) return cost; 
    int i; 
    int ans = 0; 
    int _min = NN; 
    for(i = head[u]; i != -1; i = adj[i].next) 
    { 
        int v = adj[i].v; 
        if(adj[i].w) 
        { 
            if(dis[v] + 1 == dis[u]) 
            { 
                int t = dfs(v, s, d, min(adj[i].w, cost)); 
                adj[i].w -= t; 
                adj[i ^ 1].w += t; 
                ans += t; 
                cost -= t; 
                if(dis[s] == NN) return ans; 
                if(!cost) break; 
            } 
            if(_min > dis[v]) 
                _min = dis[v]; 
        } 
    } 
    if(!ans) 
    { 
        if(-- num[dis[u]] == 0) dis[s] = NN; 
        dis[u] = _min + 1; 
        ++ num[dis[u]]; 
    } 
    return ans; 

 
int isap(int s, int d) 

    memset(dis, 0, sizeof(dis)); 
    memset(num, 0, sizeof(num)); 
    num[0] = NN; 
    int ans = 0; 
    while(dis[s] < NN) 
        ans += dfs(s, s, d, INF); 
    return ans; 

 
int main() 

    //freopen("e://data.in", "r", stdin); 
    while(scanf("%d%d%d", &N, &F, &D) != EOF) 
    { 
        int i, j; 
        int a; 
        char s[nMax]; 
        memset(head, -1, sizeof(head)); 
        cnt = 0; 
        for(i = 1; i <= F; ++ i)  
        { 
            scanf("%d", &a); 
            addEdge(0, i, a); 
        } 
        for(i = 1; i <= D; ++ i) 
        { 
            scanf("%d", &a); 
            addEdge(F + 2 * N + i, F + 2 * N + D + 1, a); 
        } 
        for(i = 1; i <= N; ++ i) 
        { 
            addEdge(F + i, F + N + i, 1); 
        } 
        for(i = 1; i <= N; ++ i) 
        { 
            scanf("%s", s + 1); 
            for(j = 1; j <= F; ++ j) 
                if(s[j] == 'Y') 
                    addEdge(j, F + i, INF); 
        } 
        for(i = 1; i <= N; ++ i) 
        { 
            scanf("%s", s + 1); 
            for(j = 1; j <= D; ++ j) 
                if(s[j] == 'Y') 
                    addEdge(F + N + i, F + 2 * N + j, INF); 
        } 
        NN = F + 2 * N + D + 2; 
        int ans = isap(0, NN - 1); 
        printf("%d\n", ans); 
    } 
    return 0; 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved