5683 道路拆除

5683 道路拆除

这个题也就是最短路径呗,挺好的,我猜猜,首先求一下最短路径然后把不是最短路径的边全部删去
很显然我猜错了
由起点开始到两个终点,很容易理解是最短路
接着想,直接最短路是行不通的,因为我们要求经过的次数,直接最短路过重复
那么怎么样子做到不重复?
5683 道路拆除
于是就要跑三遍最短路

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
struct node
{
	int to,next;
}e[100010];
int h[100010],tot,ans=0x7f7f7f;
int add(int x,int y)
{
	e[++tot].to=y;
	e[tot].next=h[x];
	h[x]=tot;
}
int n,m,s1,t1,s2,t2;
int dis1[100010],dis2[100010],dis3[100010];
void dijkstra(int *d,int a)//堆优化Dijkstra
{
	d[a]=0;
	priority_queue<pair<int,int> >q;
	q.push(make_pair(0,a));
	while(!q.empty())
	{
		int y=q.top().first,x=q.top().second;
		q.pop();
		for(int i=h[x];i;i=e[i].next)
		{
			int v=e[i].to;
			if(d[v]>d[x]+1)
			{
				d[v]=d[x]+1;//优化 
				q.push(make_pair(-d[v],v));//大小堆 
			}
		}
	}
}
int main()
{
	memset(dis1,0x7f7f7f,sizeof(dis1));
	memset(dis2,0x7f7f7f,sizeof(dis2));
	memset(dis3,0x7f7f7f,sizeof(dis3));
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int x,y;
		cin>>x>>y;
		add(x,y);
		add(y,x);
	}
	cin>>s1>>t1>>s2>>t2;
	dijkstra(dis1,1);
	dijkstra(dis2,s1);
	dijkstra(dis3,s2);
	for(int i=1;i<=n;i++)
	{
		if(dis1[i]+dis2[i]<=t1&&dis1[i]+dis3[i]<=t2)//时间限制 
		{
			ans=min(ans,dis1[i]+dis2[i]+dis3[i]);
		}
	}
	if(ans==0x7f7f7f)
		cout<<-1<<endl;
	else
		cout<<m-ans<<endl;
}
上一篇:【leetcode1696】跳跃游戏


下一篇:nlfs 20034 #12440「NOIP2021模拟赛0923北大附」入教