[CF544D]Destroying Roads_最短路_bfs
D. Destroying Roads
題目大意:
In some country there are exactly n cities and m bidirectional roads connecting the cities. Cities are numbered with integers from 1 to n. If cities a and b are connected by a road, then in an hour you can go along this road either from city a to city b, or from city b to city a. The road network is such that from any city you can get to any other one by moving along the roads.
You want to destroy the largest possible number of roads in the country so that the remaining roads would allow you to get from city s1 to city t1 in at most l1 hours and get from city s2 to city t2 in at most l2 hours.
Determine what maximum number of roads you need to destroy in order to meet the condition of your plan. If it is impossible to reach the desired result, print -1.
數據范圍:
The first line contains two integers n, m (1?≤?n?≤?3000, )?— the number of cities and roads in the country, respectively.
Next m lines contain the descriptions of the roads as pairs of integers ai, bi (1?≤?ai,?bi?≤?n, ai?≠?bi). It is guaranteed that the roads that are given in the description can transport you from any city to any other one. It is guaranteed that each pair of cities has at most one road between them.
The last two lines contains three integers each, s1, t1, l1 and s2, t2, l2, respectively (1?≤?si,?ti?≤?n, 0?≤?li?≤?n).
題解:
首先,保證了刪掉的邊最多,那就說明$s1$到$t1$和$s2$到$t2$都分別只有一條路徑,不然的話我們還可以刪掉更多的邊。
接下來我們考慮,最終答案的形式。
必定是如下三種情況之一:
第一種,這兩條路徑互不相交。就是$s1$到$t1$,$s2$到$t2$。
第二種,存在一條公共路徑,$l$到$r$,答案是$s1$到$l$,$l$到$r$,$r$到$t1$;和$s2$到$l$,$l$到$r$,$r$到$t2$。
最后一種是$s2$和$t2$調換,也就是$t2$到$l$,$l$到$r$,$r$到$s2$。
顯然,每段路徑都是最短路。
我們需要枚舉$l$和$r$,也就是說我們需要多源最短路。
但是已知的算法最快也只能做到$n^2logn$,跑$n$遍堆優化$Dijkstra$。
好慢啊.....
誒,我們發現每條邊的邊權都相等,所以我們可以直接$bfs$。
因為邊權都相等,所以每個點第一次到的時間戳就是距離。
然后枚舉更新答案就好,不要忘記了第一種情況和判斷是否超出了長度上限$l1$和$l2$。
代碼:
#include <bits/stdc++.h>#define N 3010 using namespace std;int head[N], to[N << 1], nxt[N << 1], tot;int dis[N][N];bool vis[N];queue<int > q;char *p1, *p2, buf[100000];#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000,stdin), p1 == p2) ? EOF : *p1 ++ )int rd() {int x = 0, f = 1;char c = nc();while (c < 48) {if (c == '-')f = -1;c = nc();}while (c > 47) {x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();}return x * f; }inline void add(int x, int y) {to[ ++ tot] = y;nxt[tot] = head[x];head[x] = tot; }void bfs(int x) {while (!q.empty())q.pop();memset(dis[x], 0x3f, sizeof dis[x]);memset(vis, false, sizeof vis);vis[x] = true;dis[x][x] = 0;q.push(x);while (!q.empty()) {int p = q.front(); q.pop();for (int i = head[p]; i; i = nxt[i]) {if (!vis[to[i]]) {dis[x][to[i]] = dis[x][p] + 1;vis[to[i]] = true;q.push(to[i]);}}} }int main() {int n = rd(), m = rd();for (int i = 1; i <= m; i ++ ) {int x = rd(), y = rd();add(x, y), add(y, x);}int s1 = rd(), t1 = rd(), l1 = rd();int s2 = rd(), t2 = rd(), l2 = rd();for (int i = 1; i <= n; i ++ ) {bfs(i);}if(dis[s1][t1] > l1 || dis[s2][t2] > l2)puts("-1"), exit(0);int ans = dis[s1][t1] + dis[s2][t2];for (int i = 1; i <= n ; i ++ ) {for (int j = 1; j <= n; j ++ ) {int v1, v2;v1 = dis[s1][i] + dis[i][j] + dis[j][t1];v2 = dis[s2][i] + dis[i][j] + dis[j][t2];if(v1 <= l1 && v2 <= l2)ans = min(ans, v1 + v2 - dis[i][j]);v2 = dis[s2][j] + dis[j][i] + dis[i][t2];if(v1 <= l1 && v2 <= l2)ans = min(ans, v1 + v2 - dis[i][j]);}}printf("%d\n", m - ans);return 0; }小結:好題啊。對于一個沒有思路的題,我們可以想一想最終答案的樣子。如果有沒有用上的條件,看看能不能通過那個條件來優化當前的不完美算法。
轉載于:https://www.cnblogs.com/ShuraK/p/11240535.html
總結
以上是生活随笔為你收集整理的[CF544D]Destroying Roads_最短路_bfs的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Vue利用Vue.extend()实现自
- 下一篇: 超图iserver登录密码忘记,重置密码