D. Destroying Roads time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output
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.
InputThe 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).
OutputPrint a single number — the answer to the problem. If the it is impossible to meet the conditions, print -1.
Sample test(s) input5 4 1 2 2 3 3 4 4 5 1 3 2 3 5 2output
0input
5 4 1 2 2 3 3 4 4 5 1 3 2 2 4 2output
1input
5 4 1 2 2 3 3 4 4 5 1 3 2 3 5 1output
-1
思路:其實題目的意思也就是說最少需要多少條邊使得s1到t1距離不超過l1且s2到t2距離不超過l2.如果需要的邊沒有相交那麼顯然是兩個最短路上邊,如果相交那麼應該是相交部分的最短路和相交的兩個端點到其他四個點的最短路,所以我們可以先預處理出任意兩點間的最短路,然後枚舉相交部分的兩個端點,最後用總邊數減去需要的邊數就是答案
#include#define foreach(it,v) for(__typeof((v).begin()) it = (v).begin(); it != (v).end(); ++it) using namespace std; typedef long long ll; const int inf = 1e7; const int maxn = 3000 + 5; int n,m; int d[maxn][maxn]; vector G[maxn]; void AddEdge(int u,int v) { G[u].push_back(v); G[v].push_back(u); } void bfs(int cur) { memset(d[cur],0,sizeof d[cur]); queue q; q.push(cur); while(!q.empty()) { int u = q.front(); q.pop(); foreach(it,G[u])if(!d[cur][*it]){ d[cur][*it] = d[cur][u] + 1; q.push(*it); } } for(int i = 1; i <= n; i++) if(!d[cur][i]) d[cur][i] = inf; d[cur][cur] = 0; } int main() { while(~scanf("%d%d",&n,&m)) { for(int i = 1; i <= n; i++)G[i].clear(); for(int i = 1; i <= m; i++) { int u,v;scanf("%d%d",&u,&v); AddEdge(u,v); } for(int i = 1; i <= n; i++)bfs(i); int s1,t1,l1,s2,t2,l2; scanf("%d%d%d%d%d%d",&s1,&t1,&l1,&s2,&t2,&l2); if(d[s1][t1]>l1||d[s2][t2]>l2) { puts("-1"); continue; } int res = d[s1][t1]+d[s2][t2]; for(int i = 1; i <= n; i++) { for(int j = i; j <= n; j++) { int w1 = min(d[s1][i]+d[i][j]+d[j][t1], d[s1][j]+d[j][i]+d[i][t1]); int w2 = min(d[s2][i]+d[i][j]+d[j][t2], d[s2][j]+d[j][i]+d[i][t2]); if(w1>l1||w2>l2)continue; res = min(res,w1+w2-d[i][j]); } } printf("%d\n", m - res); } return 0; }