uva 11045 uva 10330(EK最大流)

来源:互联网 发布:贝多芬第五交响曲知乎 编辑:程序博客网 时间:2024/06/06 03:39

11045:

题意:

给6种型号衣服的总总数n,然后有m个志愿者,每个志愿者适合两种型号的衣服。

问能否让每个人都发到符合他型号的衣服。


解析:

用网络流来做。

网络流最主要的就是抽象建图,图建完就好了。

源点与每种衣服型号相连,流量是每种型号衣服的数量,然后志愿者和符合他的衣服相连,权值是1,最后把志愿者和汇点相连,权值也是1。

然后求一个最大流,判断是否最大流=志愿者数就行了。


代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long longusing namespace std;const int maxn = 100 + 10;const int inf = 0x3f3f3f3f;int n, m;int cap[maxn][maxn];int a[maxn];int flow[maxn][maxn];int p[maxn];void Init(){    memset(cap, 0, sizeof(cap));    memset(flow, 0, sizeof(flow));    memset(p, 0, sizeof(p));}int change(string s){    if (s == "XS")        return 1;    if (s == "S")        return 2;    if (s == "M")        return 3;    if (s == "L")        return 4;    if (s == "XL")        return 5;    if (s == "XXL")        return 6;}int EK(int s, int t){    queue<int> q;    int res = 0;    while (1)    {        memset(a, 0, sizeof(a));        a[s] = inf;        q.push(s);        while(!q.empty())        {            int u = q.front();            q.pop();            for (int v = s; v <= t; v++)            {                if (!a[v] && flow[u][v] < cap[u][v])                {                    p[v] = u;                    a[v] = min(a[u], cap[u][v] - flow[u][v]);                    q.push(v);                }            }        }        if (a[t] == 0)            return res;        for (int u = t; u != s; u = p[u])        {            flow[p[u]][u] += a[t];            flow[u][p[u]] -= a[t];        }        res += a[t];    }}int main(){    #ifdef LOCAL    freopen("in.txt", "r", stdin);    #endif // LOCAL    int ncase;    scanf("%d", &ncase);    while (ncase--)    {        scanf("%d%d", &n, &m);        getchar();        int s, t;        s = 0, t = m + 7;        Init();        for (int i = 1; i <= 6; i++)        {            cap[s][i] += n / 6;        }        for (int i = 7; i < t; i++)        {            string a, b;            cin >> a >> b;            cap[change(a)][i]++;            cap[change(b)][i]++;            cap[i][t] = 1;        }        int ans = EK(s, t);        if (ans == m)            printf("YES\n");        else            printf("NO\n");    }    return 0;}


10330:

题意:

给几个能量交换塔,给几个容量,求最大流。


解析:

拆点建图。


代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long longusing namespace std;const int maxn = 200 + 10;const int inf = 0x3f3f3f3f;int n;int cap[maxn][maxn];int a[maxn];int flow[maxn][maxn];int p[maxn];void Init(){    memset(cap, 0, sizeof(cap));    memset(flow, 0, sizeof(flow));    memset(p, 0, sizeof(p));}int EK(int s, int t){    queue<int> q;    int res = 0;    while (1)    {        memset(a, 0, sizeof(a));        a[s] = inf;        q.push(s);        while(!q.empty())        {            int u = q.front();            q.pop();            for (int v = s; v <= t; v++)            {                if (!a[v] && flow[u][v] < cap[u][v])                {                    p[v] = u;                    a[v] = min(a[u], cap[u][v] - flow[u][v]);                    q.push(v);                }            }        }        if (a[t] == 0)            return res;        for (int u = t; u != s; u = p[u])        {            flow[p[u]][u] += a[t];            flow[u][p[u]] -= a[t];        }        res += a[t];    }}int main(){    #ifdef LOCAL    freopen("in.txt", "r", stdin);    #endif // LOCAL    while (~scanf("%d", &n))    {        Init();        int s = 0, t = 2 * n + 1;        for (int i = 1; i <= n; i++)        {            int w;            scanf("%d", &w);            cap[i][i + n] += w;        }        int m;        scanf("%d", &m);        for (int i = 1; i <= m; i++)        {            int u, v, w;            scanf("%d%d%d", &u, &v, &w);            cap[u + n][v] += w;        }        int a, b;        scanf("%d%d", &a, &b);        for (int i = 1; i <= a; i++)        {            int x;            scanf("%d", &x);            cap[s][x] = inf;        }        for (int i = 1; i <= b; i++)        {            int x;            scanf("%d", &x);            cap[x + n][t] = inf;        }        printf("%d\n", EK(s, t));    }    return 0;}


0 0
原创粉丝点击