bzoj1433_maximum flow | bipartite graph maximum matching

After adjusting the network flow for an afternoon, I finally found that when I wanted to traverse with 0 as the subscript, I still used the habitual writing method, which was simply unhappy.

The problem of network flow basically focuses on modeling. Let's take a look at how to model this problem: First, the number of students and the number of available beds are determined, and we create a source point and a sink point by ourselves. Considering that all students must have a bed, the flow from the origin to the bed and then to the students can be done. At this time, we can tactfully discover one thing, which is actually to seek the maximum matching of a bipartite graph, and angrily feel that we have been pitted. In the end, it is only necessary to see if the number of matches is equal to the number of students in need.

Another thing is to judge students in need, as long as they are outside or on-campus but not going home, they are in need.

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cstdlib>
#define N 200
#define M 20000
#define INF 10000000

using namespace std;

struct edge
{
    int to, next;
}e[M];
int t, n, num, ans, cont;
int a[N], b[N], p[N], mat[N], flag[N];
void add(int x, int y)
{
    e[num].to = y;
    e[num].next = p[x];
    p[x] = num++;
}
void clean()
{
    ans = num = cont = 0;
    memset(p, -1, sizeof p);
    memset(e, 0, sizeof e);
    memset(mat, 0, sizeof mat);
}
void init()
{
    clean();
    int x;
    scanf("%d", &n);
    t = n << 1 | 1;
    for (int i = 1; i <= n; ++i)
    scanf("%d", &a[i]);
    for (int i = 1; i <= n; ++i)
    scanf("%d", &b[i]);
    for (int i = 1; i <= n; ++i)
    if (!a[i] || (a[i] && !b[i])) ++cont;
    for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n; ++j)
    {
        scanf("%d", &x);
        if (((i == j && a[i]) || (x && a[j])) && (!a[i] || (a[i] && !b[i])))
        {
            add(j+n, i);
            add(i, j+n);
        }
    }
}
bool find(int x)
{
    for (int i = p[x]; i != -1; i = e[i].next)
    {
        int k = e[i].to;
        if (!flag[k])
        {
            flag[k] = 1;
            if (!mat[k] || find(mat[k]))
            {
                mat[k] = x;
                return true;
            }
        }
    }
    return false;
}
void deal()
{
    for (int i = 1; i <= n; ++i)
    {
        memset(flag, 0, sizeof flag);
        ans += find(i);
    }
    if (ans == cont) printf("^_^\n");
    else printf("T_T\n");
}
int main()
{
    freopen("a.in", "r", stdin);
    int T;
    scanf("%d", &T);
    while(T--)
    {
        init();
        deal();
    }
    return 0;
}//二分图匹配代码

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cstdlib>
#define N 200
#define M 20000
#define INF 10000000

using namespace std;

struct edge
{
    int to, next, cap, flow;
}e[M];
int t, n, num, ans, cont;
int a[N], b[N], p[N], d[N], flag[N], now[N];
void add(int x, int y, int z)
{
    e[num].to = y;
    e[num].next = p[x];
    e[num].cap = z;
    p[x] = num++;
}
void clean()
{
    ans = num = cont = 0;
    memset(p, -1, sizeof p);
    memset(d, 0, sizeof d);
    memset(e, 0, sizeof e);
}
void init()
{
    clean();
    int x;
    scanf("%d", &n);
    t = n << 1 | 1;
    for (int i = 1; i <= n; ++i)
    scanf("%d", &a[i]);
    for (int i = 1; i <= n; ++i)
    scanf("%d", &b[i]);
    for (int i = 1; i <= n; ++i)
    if (!a[i] || (a[i] && !b[i]))
    {
        add(i, t, 1);
        add(t, i, 0);
        ++cont;
    }
    for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n; ++j)
    {
        scanf("%d", &x);
        if (((i == j && a[i]) || (x && a[j])) && (!a[i] || (a[i] && !b[i])))
        {
            add(j+n, i, 1);
            add(i, j+n, 0);
        }
    }
    for (int i = 1; i <= n; ++i)
    if (a[i])
    {
        add(0, i+n, 1);
        add(i+n, 0, 0);
    }
}
bool bfs()
{
    memset(flag, 0, sizeof flag);
    d[0] = 0, flag[0] = 1;
    queue<int>q;
    q.push(0);
    while(!q.empty())
    {
        int x = q.front();
        q.pop();
        for (int i = p[x]; i != -1; i = e[i].next)
        {
            int k = e[i].to;
            if (!flag[k] && e[i].cap > e[i].flow)
            {
                flag[k] = 1;
                d[k] = d[x] + 1;
                q.push(k);
            }
        }
    }
    for (int i = 0; i <= t; ++i) now[i] = p[i];
    return flag[t];
}
int dfs(int x, int mini)
{
    if (x == t || !mini) return mini;
    int flow = 0;
    for (int i = now[x]; i != -1; i = e[i].next)
    {
        now[x] = i;
        int k = e[i].to;
        if (d[k] == d[x] + 1)
        {
            int tmp = dfs(k, min(mini, e[i].cap-e[i].flow));
            if (tmp <= 0) continue;
            e[i].flow += tmp;
            e[i^1].flow -= tmp;
            flow += tmp;
            mini -= tmp;
            if (!mini) break;
        }
    }
    return flow;
}
void deal()
{
    while(bfs()) ans += dfs(0, INF);
    if (ans == cont) printf("^_^\n");
    else printf("T_T\n");
}
int main()
{
    freopen("a.in", "r", stdin);
    freopen("a.out", "w", stdout);
    int T;
    scanf("%d", &T);
    while(T--)
    {
        init();
        deal();
    }
    return 0;
}//网络流代码



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326385643&siteId=291194637
Recommended