#6RE求助
查看原帖
#6RE求助
261935
Unique_Hanpi楼主2021/12/17 08:37

RT

//P3356 火星探险问题
#include <bits/stdc++.h>
using namespace std;

const int MAXN = 2230;
const int INF = 0x3fffffff;

int n, p, q, s = 0, t;
int head[MAXN], edge_num = 1;

struct edge {
    int nxt, to, w, cost;
    int d;
} G[MAXN * 20];

inline int trans(int x, int y) {return p * (x - 1) + y;}

inline void add(int u, int v, int w, int c, int d) {
    G[++edge_num] = (edge) {head[u], v, w, c, d};
    head[u] = edge_num;
    G[++edge_num] = (edge) {head[v], u, 0, -c, d};
    head[v] = edge_num;
}

int dis[MAXN], pre[MAXN];
bool vis[MAXN];

inline bool SPFA() {
    memset(dis, 0x3f, sizeof(dis));
    memset(vis, 0, sizeof(vis));
    dis[s] = 0; pre[t] = -1;
    queue<int> Q;
    Q.push(s);
    while (!Q.empty()) {
        int top = Q.front();
        Q.pop();
        vis[top] = 0;
        for (int i = head[top]; i; i = G[i].nxt) {
            int v = G[i].to;
            if (!G[i].w || dis[v] <= dis[top] + G[i].cost) continue;
            dis[v] = dis[top] + G[i].cost;
            pre[v] = i;
            if (!vis[v]) {
                vis[v] = 1;
                Q.push(v);
            }
        }
    }
    return pre[t] != -1;
}

int main() {
    scanf("%d%d%d", &n, &p, &q);
    t = 2 * p * q + 1;
    for (int i = 1; i <= q; i++) {
        for (int j = 1; j <= p; j++) {
            int temp;
            scanf("%d", &temp);
            if (temp == 1) continue;
            int num = trans(i, j);
            if (temp == 2) add(num, num + p*q, 1, -1, 0);
            add(num, num + p*q, INF, 0, 0);
            if (i < q) add(num + p*q, trans(i + 1, j), INF, 0, 0);
            if (j < p) add(num + p*q, trans(i, j + 1), INF, 0, 1);
        }
    }

    add(s, 1, n, 0, 0);
    add(t - 1, t, INF, 0, 0);

    while (SPFA()) {
        int cur = t;
        while (cur != s) {
            G[pre[cur]].w--;
            G[pre[cur] ^ 1].w++;
            cur = G[pre[cur] ^ 1].to;
        }
    }

    if (G[head[s]].w) return 0;//无路可走
    for (int i = 1; i <= n; i++) {
        int cur = p*q + 1;
        while (cur != t - 1) {
            for (int j = head[cur]; j; j = G[j].nxt) if (G[j].to != cur - p*q && G[j].w < INF) {
                printf("%d %d\n", i, G[j].d);
                G[j].w++;
                cur = G[j].to + p*q;
                break;
            }
        }
    }
    return 0;
}
2021/12/17 08:37
加载中...