题目大意:给出n个点,m条边,边之间路径长度为1,给出s1,t1,d1,s2,t2,d2,为使s1到t1的距离最多为d1,s2到t2的距离最多为d2,求图中在满足此条件下最多可以删除多少条边
解题思路:先分别求出s1到t1的最短距离,s2到t2的最短距离,若最短距离大于相应的d1或d2,则不成立,否则,用总边数-构成最短路所需边数,看最短距离是否有重边(注意考虑顺序)
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <list>
using namespace std;
const int maxn = 3000 + 10;
int d[maxn][maxn];
int vis[maxn];
int main()
{
int n,m;
int u,v;
vector<int> G[maxn];
int s1,s2,t1,t2,d1,d2;
scanf("%d%d",&n,&m);
for(int i = 1; i <= m; i++)
{
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
scanf("%d%d%d%d%d%d",&s1,&t1,&d1,&s2,&t2,&d2);
for(int i = 1; i <= n; i++)
{
memset(vis,0,sizeof(vis));
queue<int> q;
q.push(i);
vis[i]=1;
while(!q.empty())
{
int v=q.front();
q.pop();
for(int j=0;j<G[v].size();j++)
{
int u=G[v][j];
if(vis[u])
continue;
vis[u]=1;
d[i][u]=d[i][v]+1;
q.push(u);
}
}
}
if(d[s1][t1] > d1 || d[s2][t2] > d2)
{
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++)
{
if(d[s1][i]+d[i][j]+d[j][t1] <= d1 && d[s2][i]+d[i][j]+d[j][t2] <= d2)
ans = min(ans,d[s1][i]+d[i][j]+d[j][t1]+d[s2][i]+d[j][t2]);
if(d[s1][i]+d[i][j]+d[j][t1] <= d1 && d[t2][i]+d[i][j]+d[j][s2] <= d2)
ans=min(ans,d[s1][i]+d[i][j]+d[j][t1]+d[t2][i]+d[j][s2]);
}
}
cout<<m-ans<<endl;
return 0;
}