Title
Give an interval [l, r] [l, r][l,r ] , allowing the following operations:
- Put [l, r] [l, r][l,r ] turns into[l − 1, r] [l-1, r][l−1,r ] or[l + 1, r] [l + 1, r][l+1,r]
- Put [l, r] [l, r][l,r ] turns into[l, r − 1] [l, r-1][l,r−1 ] 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 l≤r 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
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
Separate the useful elements in the dual graph to get
(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;
}