bzoj1452 最大流

很明显最大流。。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int, int>

using namespace std;

const int N = 150 + 7;
const int M = 1e4 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 +7;

int a[N], b[N], Map[N][N], head[N], level[N], n, sum, tot, S, T;

struct node {
    int to, w, nx;
} edge[N * N];

void add(int u, int v, int w) {
    edge[tot].to = v;
    edge[tot].w = w;
    edge[tot].nx = head[u];
    head[u] = tot++;

    edge[tot].to = u;
    edge[tot].w = 0;
    edge[tot].nx = head[v];
    head[v] = tot++;
}


bool bfs() {
    memset(level, 0, sizeof(level));
    queue<int> que; level[S] = 1; que.push(S);
    while(!que.empty()) {
        int u = que.front(); que.pop();
        if(u == T) return true;
        for(int i = head[u]; ~i; i = edge[i].nx) {
            int v = edge[i].to, w = edge[i].w;
            if(level[v] || w <= 0) continue;
            level[v] = level[u] + 1;
            que.push(v);
        }
    }
    return false;
}

int dfs(int u, int p) {
    if(u == T) return p;
    int ret = 0;
    for(int i = head[u]; ~i; i = edge[i].nx) {
        int v = edge[i].to, w = edge[i].w;
        if(level[v] != level[u] + 1 || w <= 0) continue;
        int f = dfs(v, min(w, p - ret));
        ret += f;
        edge[i].w -= f;
        edge[i ^ 1].w += f;
        if(ret == p) break;
    }
    if(!ret) level[u] = 0;
    return ret;
}

int Dinic() {
    int ans = 0;
    while(bfs()) ans += dfs(S, inf);
    return ans;
}
void init() {
    memset(head, -1, sizeof(head));
    tot = 0; sum = 0;
}

int main() {

    int cas; scanf("%d", &cas);
    while(cas--) {
        init();
        scanf("%d", &n);
        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++)
            for(int j = 1; j <= n; j++)
                scanf("%d", &Map[i][j]);

        for(int i = 1; i <= n; i++)
            Map[i][i] = 1;

        S = 0, T = 2 * n + 1;

        for(int i = 1; i <= n; i++)
            if(!a[i] || (a[i] && !b[i]))
                add(S, i, 1), sum++;

        for(int i = 1; i <= n; i++)
            if(a[i]) add(i + n, T, 1);

        for(int i = 1; i <= n; i++) {
            if(a[i] && b[i]) continue;
            for(int j = 1; j <= n; j++) {
                if(Map[i][j] && a[j]) {
                    add(i, j + n, 1);
                }
            }
        }

        if(Dinic() == sum) printf("%c%c%c\n", 94, 95, 94);
        else printf("%c%c%c\n", 84, 95, 84);
    }
    return 0;
}
/*
*/

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/9279292.html