这是一道C++题目,请通过最少的修改使代码AC:

P1004 [NOIP 2000 提高组] 方格取数

题目背景

NOIP 2000 提高组 T4

题目描述

设有 N×NN \times N 的方格图 (N9)(N \le 9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字 00。如下图所示(见样例):

某人从图的左上角的 AA 点出发,可以向下行走,也可以向右走,直到到达右下角的 BB 点。在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字 00)。
此人从 AA 点到 BB 点共走两次,试找出 22 条这样的路径,使得取得的数之和为最大。

输入格式

输入的第一行为一个整数 NN(表示 N×NN \times N 的方格图),接下来的每行有三个整数,前两个表示位置,第三个数为该位置上所放的数。一行单独的 00 表示输入结束。

输出格式

只需输出一个整数,表示 22 条路径上取得的最大的和。

输入输出样例 #1

输入 #1

8
2 3 13
2 6  6
3 5  7
4 4 14
5 2 21
5 6  4
6 3 15
7 2 14
0 0  0

输出 #1

67

说明/提示

数据范围:1N91\le N\le 9。 以下是我的代码:

#include <bits/stdc++.h>
using namespace std;

const int INF = 1e9;
struct Dinic {
    struct Edge { int to, cap, rev; };
    
    int n, s, t;
    vector <vector<Edge> > g;
    vector <int> level, it;
    
    Dinic(int n) : n(n), g(n), level(n), it(n) {}
    
    void addEdge(int from, int to, int cap) {
        g[from].push_back({to, cap, (int)g[to].size()});
        g[to].push_back({from, 0, (int)g[from].size() - 1});
    }
    
    bool bfs() {
        fill(level.begin(), level.end(), -1);
        queue<int> q;
        level[s] = 0;
        q.push(s);
        while (!q.empty()) {
            int u = q.front(); q.pop();
            for (auto &e : g[u]) {
                if (e.cap > 0 && level[e.to] < 0) {
                    level[e.to] = level[u] + 1;
                    q.push(e.to);
                }
            }
        }
        return level[t] >= 0;
    }
    
    int dfs(int u, int f) {
        if (u == t) return f;
        for (int &i = it[u]; i < (int)g[u].size(); ++i) {
            auto &e = g[u][i];
            if (e.cap > 0 && level[e.to] == level[u] + 1) {
                int ret = dfs(e.to, min(f, e.cap));
                if (ret > 0) {
                    e.cap -= ret;
                    g[e.to][e.rev].cap += ret;
                    return ret;
                }
            }
        }
        return 0;
    }
    
    int max_flow(int S, int T) {
        s = S; t = T;
        int flow = 0, inf = 1e9;
        while (bfs()) {
            fill(it.begin(), it.end(), 0);
            while (int f = dfs(s, inf)) flow += f;
        }
        return flow;
    }
};

int main() {
    int N;
    cin >> N;
    vector<vector<int> > grid(N,vector<int>(N,0));
    for (int i = 0; ; ++i) {
        int u, v, w;
        cin >> u >> v >> w;
        if(u==0&&v==0&&w==0){
            break;
        }
        grid[u-1][v-1] = w;
    }
    int total_nodes = 2 * N * N + 3;
    Dinic dinic(total_nodes);
    int source = 0;
    int sink = 2 * N * N + 1;
    int aux_node = 2 * N * N + 2;
    dinic.addEdge(source, 1, 2);

    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            int in_node = 1 + i * N + j;
            int out_node = 1 + N * N + i * N + j;
            dinic.addEdge(in_node, aux_node, 1);
            dinic.addEdge(aux_node, out_node, grid[i][j]);
            dinic.addEdge(in_node, out_node, 1);
            if (j + 1 < N) {
                int next_in = 1 + i * N + (j + 1);
                dinic.addEdge(out_node, next_in, 2);
            }
            if (i + 1 < N) {
                int next_in = 1 + (i + 1) * N + j;
                dinic.addEdge(out_node, next_in, 2);
            }
        }
    }
    int end_out = 1 + N * N + (N - 1) * N + (N - 1);
    dinic.addEdge(end_out, sink, 2);
    int max_flow = dinic.max_flow(source, sink);
    cout << max_flow << endl;

    return 0;
}

0 条评论

目前还没有评论...