uva 10330 最大流

来源:互联网 发布:c语言getchar用法 编辑:程序博客网 时间:2024/05/22 16:59

拆点  将节点 i 的容量拆成从 i 到 i+n 的边的容量 套用最大流模板 ac

#include <cstdio>#include <cstdlib>#include <cmath>#include <map>#include <set>#include <queue>#include <stack>#include <vector>#include <sstream>#include <string>#include <cstring>#include <algorithm>#include <iostream>#define maxn 210#define INF 0x7fffffff#define inf 10000000#define MOD 1000000007#define ull unsigned long long#define ll long longusing namespace std;int n, cap[maxn][maxn], a[maxn], m, flow[maxn][maxn], p[maxn];int maxflow(){    queue<int> q;    int f = 0;    memset(flow, 0, sizeof(flow));    while(true)    {        memset(a, 0, sizeof(a));        a[0] = inf;        q.push(0);        while(!q.empty())        {            int u = q.front();            q.pop();            for(int i = 1; i <= n; ++ i)            {                if(!a[i] && cap[u][i] > flow[u][i])                {                    p[i] = u;                    q.push(i);                    a[i] = min(a[u], cap[u][i]-flow[u][i]);                }            }        }        if(!a[n]) break;        for(int i = n; i != 0; i = p[i])        {            flow[p[i]][i] += a[n];            flow[i][p[i]] -= a[n];        }        f += a[n];    }    return f;}int main(){    while(scanf("%d", &n) == 1)    {        memset(cap, 0, sizeof(cap));        for(int i = 1; i <= n; ++ i)        {            int temp;            scanf("%d", &temp);            cap[i][i+n] = temp;        }        scanf("%d", &m);        for(int i = 0; i < m; ++ i)        {            int x, y, c;            scanf("%d%d%d", &x, &y, &c);            cap[x+n][y] = c;        }        int a, b;        scanf("%d%d", &a, &b);        for(int i = 0; i < a; ++ i)        {            int x;            scanf("%d", &x);            cap[0][x] = inf;        }        for(int i = 0; i < b; ++ i)        {            int x;            scanf("%d", &x);            cap[x+n][2*n+1] = inf;        }        n = n*2+1;        printf("%d\n", maxflow());    }    return 0;}


0 0