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;
}