在某一个国家,那儿有n个城市,他们通过m条双向道路相连。城市从1到n编号。如果城市a和b通过一条道路直接相连,那么他们之间的距离就是一个小时。这个国家的道路网络可以允许你从任意一个城市到达另外的城市。
现在你要破坏尽可能多的道路,但是要保证从城市s1到t1不超过l1小时,并且从城市s2到t2不超过l2小时。
输出最多可以破坏的道路数目,如果没有解,请输出-1
Input
单组测试数据。 第一行有两个整数n,m(1 ≤ n ≤ 3000, n-1 ≤ m ≤ min(3000,n*(n-1)/2) )。 接下来m行,每行有两个整数 ai, bi (1 ≤ ai, bi ≤ n, ai ≠ bi),表示ai和bi之间有一条道路。 输入保证是一个连通图。 最后两行每行有三个整数s1, t1, l1和 s2, t2, l2, (1 ≤ si, ti ≤ n, 0 ≤ li ≤ n)。
Output
输出一个整数,表示最多可以破坏的道路数目,如果没有解,输出-1。
Input示例
5 4 1 2 2 3 3 4 4 5 1 3 2 3 5 2
Output示例
0
这两条路径可能不会相交,那么必然是s1到t1的最短路径和s2到t2的最短路径之和
若相交,枚举相交的路径i->j求出最短路径
1.s1->i->j->t1, s2->i->j->t2;
2.s1->i->j->t1, s2->j->i->t2
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#define maxn 3005
#define MOD 1000000007
using namespace std;
typedef long long ll;
int d[maxn][maxn];
vector<int> v[maxn];
void bfs(int j){
queue<int> q;
q.push(j);
while(!q.empty()){
int h = q.front();
q.pop();
for(int i = 0; i < v[h].size(); i++){
int f = v[h][i];
if(d[j][f] != -1)
continue;
d[j][f] = d[j][h] + 1;
q.push(f);
}
}
}
int main(){
// freopen("in.txt", "r", stdin);
int n, m, a, b;
int s1, t1, l1, s2, t2, l2;
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++){
scanf("%d%d", &a, &b);
v[a].push_back(b);
v[b].push_back(a);
}
scanf("%d%d%d", &s1, &t1, &l1);
scanf("%d%d%d", &s2, &t2, &l2);
memset(d, -1, sizeof(d));
for(int i = 1; i <= n; i++){
d[i][i] = 0;
bfs(i);
}
if(d[s1][t1] > l1 || d[s2][t2] > l2){
puts("-1");
return 0;
}
int ans = d[s1][t1] + d[s2][t2];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++){
int p = d[s1][i] + d[s2][i] + d[i][j] + d[j][t1] + d[j][t2];
int k1 = d[s1][i] + d[i][j] + d[j][t1];
int k2 = d[s2][i] + d[i][j] + d[j][t2];
if(k1 <= l1 && k2 <= l2 && p < ans)
ans = p;
p = d[s1][i] + d[s2][j] + d[i][j] + d[j][t1] + d[i][t2];
k2 = d[s2][j] + d[i][j] + d[i][t2];
if(k1 <= l1 && k2 <= l2 && p < ans)
ans = p;
}
printf("%d\n", m - ans);
return 0;
}