D104 BFS最短路 P5683 [CSP-J2019 江西] 道路拆除

D104 BFS最短路 P5683 [CSP-J2019 江西] 道路拆除_哔哩哔哩_bilibili

 

P5683 [CSP-J2019 江西] 道路拆除 - 洛谷

给一个边权为 1 的无向图,求最多去掉多少边,使得 1 到 $s_1$ 的距离不超过 $t_1$ 且 1 到 $s_2$ 的距离不超过 $t_2$。

思路

我们考虑最少保留多少边,也就是求满足条件的最短路

分别以 $1、s_1、s_2$ 为起点跑最短路 BFS,预处理出各点到起点的距离 $d_1、d_2、d_3$

枚举各点为中心,如果满足 d1[i]+d2[i]<=t1 && d1[i]+d3[i]<=t2,最小化 d1[i]+d2[i]+d3[i]

image

 

// 多起点最短路+拼接优选 BFS 算法 O(N+M)
#include <bits/stdc++.h>
using namespace std;

const int N=3005;
vector<int> e[N]; 
int n,m,s1,t1,s2,t2,ans=2e9;
int d1[N],d2[N],d3[N];

void bfs(int s,int*d){
  memset(d,0x3f,sizeof(d1)); d[s]=0;
  queue<int> q;
  q.push(s);
  while(!q.empty()){
    int u=q.front();q.pop();
    for(auto v:e[u]){
      if(d[v]>d[u]+1){
        d[v]=d[u]+1;
        q.push(v);
      }
    }
  }
}
int main(){
  scanf("%d%d",&n,&m);
  for(int i=1,x,y;i<=m;i++){
    scanf("%d%d",&x,&y);
    e[x].push_back(y);
    e[y].push_back(x);
  }
  
  scanf("%d%d%d%d",&s1,&t1,&s2,&t2);
  bfs(1,d1);
  if(d1[s1]>t1 || d1[s2]>t2){
    puts("-1"); return 0;
  }
  bfs(s1,d2); 
  bfs(s2,d3);
  for(int i=1;i<=n;i++)if(d1[i]+d2[i]<=t1&&d1[i]+d3[i]<=t2) 
    ans=min(ans,d1[i]+d2[i]+d3[i]);
  printf("%d",m-ans);
}

 

posted @ 2026-03-12 18:44  董晓  阅读(77)  评论(0)    收藏  举报