[2020 Niuke Multi-School] 2020 Niuke Summer Multi-School Training Camp (Second Session) I-Interval——Maximum Circulation Dual Diagram Seeking the Shortest Path

Topic link

Title

Give an interval [l, r] [l, r][l,r ] , allowing the following operations:

  1. Put [l, r] [l, r][l,r ] turns into[l − 1, r] [l-1, r][l1,r ] or[l + 1, r] [l + 1, r][l+1,r]
  2. Put [l, r] [l, r][l,r ] turns into[l, r − 1] [l, r-1][l,r1 ] or[l, r + 1] [l, r + 1][l,r+1]

且保证 l ≤ r   a n d   l > 0   r ≤ n l \leq r \space and \space l > 0 \space r \leq n lr a n d l  >0 r n

But given a series of restrictions l, r, dir, cl, r, dir, cl,r,d i r ,c , which means that the current interval is[l, r] [l, r][l,r ] , the current interval cannot be operated1 11 (dir = L) or operation2 22 (dir = R), andccis required to enable this restrictionc cost
You can choose whether to enable this restriction

Ask how much it takes to achieve at least not to the interval [1, n] [1, n][1,n ] becomesl = rl = rl=The interval of r .

analysis

From 1, n 1, n1,Can n be transformed intol = rl = rl=r can be calculated by the shortest path.
But it is impossible to knowhow many restrictions are requiredwhen the shortest path cannot be reached (that is, the problemcannot bechanged), and what these conditions are.
So use the maximum flow to solve

Maximum flow

Draw a grid diagram
Connect all the two states that can be converted with edges, if there are restrictions, limit the flow to the cost, if there are no restrictions, set it to INF INFThe I N F.
For the whole matrix, it requires only half-way point for the construction of FIG., It will sink in the other half point. Alll = rl = rl=The point of r is connected to the sink point, and the source point is[1, n] [1, n][1,n ]The
following figure can be obtained for the sample

Example:
3 4
1 3 L 10
1 3 R 3
1 2 L 1
1 2 R 1

figure 1
In addition, the picture omitted [2, 3] → [2, 2] [2, 3] \rightarrow [2, 2][2,3][2,2 ] connection, its flow isINF INFINF

You can find the answer directly from the maximum flow

But will TLE

Dual graph

Dual graph Wikipedia (https://en.wikipedia.org/wiki/Dual_graph)

Through the dual graph, you can quickly convert a grid network graph from seeking the maximum flow into seeking the shortest path

Please refer to the information for the explanation of the dual graph

Draw the dual graph on the original image to get

Dual graph

Separate the useful elements in the dual graph to get

Dual graph
(The edges without edge weights in the figure are all 0 00

Can be solved quickly by the shortest path

AC code

#include <bits/stdc++.h>

using namespace std;

#define ll long long
const int maxn = 510;

int n, m;
ll dis[maxn * maxn];
char si;
vector<pair<ll, int>> G[maxn * maxn];

void addedge(int u, int v, int cost) {
    
    
    G[u].push_back({
    
    cost, v});
}

ll dijkstra(int s, int t) {
    
    
    memset(dis, 0x3f, sizeof(dis));
    dis[s] = 0;
    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> q;
    q.push({
    
    0ll, s});
    while (!q.empty()) {
    
    
        ll u = q.top().second, c = q.top().first;
        q.pop();
        if (dis[u] < c)continue;
        for (auto i : G[u]) {
    
    
            ll cc = i.first, v = i.second;
            if (dis[v] > dis[u] + cc) {
    
    
                dis[v] = dis[u] + cc;
                q.push({
    
    dis[v], v});
            }
        }
    }
    return dis[t];
}

inline int id(int x, int y) {
    
    
    return x * (n + 3) + y;
}

void solve() {
    
    
    cin >> n >> m;
    for (int i = 0; i < m; ++i) {
    
    
        int u, v, w;
        char c;
        cin >> u >> v >> c >> w;
        if (c == 'L') {
    
    
            addedge(id(u, v), id(u, v + 1), w);
            addedge(id(u, v + 1), id(u, v), w);
        } else {
    
    
            addedge(id(u, v), id(u - 1, v), w);
            addedge(id(u - 1, v), id(u, v), w);
        }
    }

    for (int i = 1; i <= n; ++i) {
    
    
        addedge(id(0, 0), id(0, i), 0);
        addedge(id(i, n + 1), id(n + 1, n + 1), 0);
    }

    dijkstra(id(0, 0), id(n + 1, n + 1));
    if (dis[id(n + 1, n + 1)] >= 0x3f3f3f3f3f3f3f3f)
        cout << -1 << endl;
    else
        cout << dis[id(n + 1, n + 1)] << endl;
}

signed main() {
    
    
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
#ifdef ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    int test_index_for_debug = 1;
    char acm_local_for_debug;
    while (cin >> acm_local_for_debug) {
    
    
        if (acm_local_for_debug == '$') exit(0);
        cin.putback(acm_local_for_debug);
        if (test_index_for_debug > 20) {
    
    
            throw runtime_error("Check the stdin!!!");
        }
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    }
#else
    solve();
#endif
    return 0;
}

Guess you like

Origin blog.csdn.net/m0_43448982/article/details/107381264