Destroying Roads

题目链接

\(Destroying\)

分析

又是变形了的最短路
我们可以考虑哪些道路必须被保留
然后枚举两个起点到终点重复的道路
考虑公合法用这些道路就可以了

\(Code\)

#include<cstdio>
#include<queue>
#include<cstring>
#include<iostream> 
using namespace std;

const int N = 3005;
int n , m , s1 , t1 , l1 , s2 , t2 , l2;
int tot , h[N] , dis[N][N] , vis[N];
struct edge{int to , nxt;}e[2 * N];
struct node{
	int id , d;
	bool operator < (node c) const {return d > c.d;}
};
priority_queue<node> Q;

inline void add(int x , int y){e[++tot] = edge{y , h[x]} , h[x] = tot;}

void dijkstra(int s)
{
	while (!Q.empty()) Q.pop();
	memset(vis , 0 , sizeof vis);
	Q.push(node{s , dis[s][s] = 0});
	while (!Q.empty())
	{
		node now = Q.top(); Q.pop();
		int u = now.id;
		if (vis[u]) continue;
		vis[u] = 1;
		for(register int i = h[u]; i; i = e[i].nxt)
		{
			int v = e[i].to;
			if (dis[s][u] + 1 < dis[s][v])
			{
				dis[s][v] = dis[s][u] + 1;
				Q.push(node{v , dis[s][v]});
			}
		}
	}
}

int main()
{
	scanf("%d%d" , &n , &m);
	int x , y;
	for(register int i = 1; i <= m; i++) 
		scanf("%d%d" , &x , &y) , add(x , y) , add(y , x);
	scanf("%d%d%d%d%d%d" , &s1 , &t1 , &l1 , &s2 , &t2 , &l2);
	memset(dis , 0x3f3f3f3f , sizeof dis);
	for(register int i = 1; i <= n; i++) dijkstra(i);
	if (dis[s1][t1] > l1 || dis[s2][t2] > l2)
	{
		printf("-1");
		return 0;
	}
	int ans = dis[s1][t1] + dis[s2][t2];
	for(register int i = 1; i <= n; i++)
		for(register int j = 1; j <= n; j++)
		{
			x = dis[s1][i] + dis[i][j] + dis[j][t1];
			y = dis[s2][i] + dis[i][j] + dis[j][t2];
			if (x <= l1 && y <= l2)
				ans = min(ans , x + y - dis[i][j]);
			y = dis[t2][i] + dis[i][j] + dis[j][s2];
			if (x <= l1 && y <= l2)
				ans = min(ans , x + y - dis[i][j]);
		}
	printf("%d" , m - ans);
}
posted @ 2020-10-16 13:01  leiyuanze  阅读(72)  评论(0编辑  收藏  举报