codeforces round# 302(div 2 D)(思路)
2015-09-15 09:33
471 查看
本题目要让删除尽量多的边,使得图上存在一条从s1 -> t1 不超过 l1 的路径,和一条从s2 -> t2 不超过 l2 的路径。因为点数不超过3000,边数也不超过3000,且边权都为1
那么直接bfs求出任意两点的最短路径。
然后直接枚举重叠部分的两个点,重叠的起点和重叠终点然后暴力就可以了。
那么直接bfs求出任意两点的最短路径。
然后直接枚举重叠部分的两个点,重叠的起点和重叠终点然后暴力就可以了。
//#pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <set> #include <map> #include <string> #include <list> #include <cstdlib> #include <queue> #include <stack> #include <cmath> #include <bitset> #include <cassert> #define ALL(a) a.begin(), a.end() #define clr(a, x) memset(a, x, sizeof a) #define fst first #define snd second #define pb push_back #define lowbit(x) (x&(-x)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define rep1(i,x,y) for(int i=x;i<=y;i++) #define rep(i,n) for(int i=0;i<(int)n;i++) using namespace std; const double eps = 1e-10; typedef long long LL; typedef long long ll; typedef pair<int, int> pii; const int oo =0x3f3f3f3f; const int N = 3030; vector<int> G ; int d ,n,m; void bfs(int s){ queue<int> Q; Q.push(s); clr(d[s],oo); d[s][s] = 0; while(!Q.empty()){ int u = Q.front(); Q.pop(); rep(i,G[u].size()) if(d[s][G[u][i]]>d[s][u]+1){ d[s][G[u][i]] = d[s][u]+1; Q.push(G[u][i]); } } } int s1,t1,l1,s2,t2,l2; int main() { scanf("%d %d",&n,&m); rep1(i,1,m){ int x,y; scanf("%d %d",&x,&y); G[x].push_back(y); G[y].push_back(x); } scanf("%d %d %d",&s1,&t1,&l1); scanf("%d %d %d",&s2,&t2,&l2); rep1(i,1,n) bfs(i); if(d[s1][t1] > l1 || d[s2][t2] > l2){ printf("-1\n"); return 0; } int ans = d[s1][t1] + d[s2][t2]; rep1(i,1,n) rep1(j,1,n){ if(d[i][j]==oo) continue; if(d[s1][i]+d[i][j]+d[j][t1]<=l1 && d[s2][i]+d[i][j]+d[j][t2]<=l2) 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]<=l1 && d[t2][i]+d[i][j]+d[j][s2]<=l2) ans = min(ans,d[s1][i]+d[i][j]+d[j][t1]+d[t2][i]+d[j][s2]); } printf("%d\n",m - ans); return 0; }