题目链接:点击打开链接
题意:n个点,m条边,起点s,终点m,每条边的权值为1,问是否能在不连通的点之间加一条边,使s到m的最短路不变。若能统计出来有多少条。
题解:最短路加上一点小判定,就能过,求一边s到各点的最短路,再求一边t到各点的最短路,然后分别去计算 dis1【i】 + 1 + did2【j】> dis1【t】 和 dis2【i】 + 1 + did2【j】> dis1【t】,若同时满足,结果+1,
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 3e3+5;
const int inf = 1e9;
struct Edge{
int v;
int w;
int next;
}edge[maxn];
int dis1[maxn];
int dis2[maxn];
int book[maxn][maxn];
int cnt;
int n,m,s,t;
int head[maxn];
void add(int u,int v){
edge[cnt].v = v;
edge[cnt].w = 1;
edge[cnt].next = head[u];
head[u] = cnt++;
}
void spfa(int s,int dis[]){
queue<int> q;
while(!q.empty()){
q.pop();
}
for(int i = 0 ; i <= n ; i ++){
dis[i] = inf;
}
int vis[maxn];
memset(vis,0,sizeof(vis));
vis[s] = 1;
dis[s] = 0;
q.push(s);
while(!q.empty()){
int u = q.front();
vis[u] = 0;
q.pop();
for(int i = head[u] ; i != -1 ; i = edge[i].next){
int v = edge[i].v;
if(dis[v] > dis[u] + edge[i].w){
dis[v] = dis[u] + edge[i].w;
if(!vis[v]){
vis[v] = 1;
q.push(v);
}
}
}
}
}
int main(){
cnt = 0;
memset(head,-1,sizeof(head));
memset(book,0,sizeof(book));
cin >> n >> m >> s >> t;
for(int i = 1; i <= m ; i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
book[u][v] = book[v][u] = 1;
}
spfa(s,dis1);
// for(int i = 1 ; i <= n ; i ++){
// cout << dis1[i] << " " ;
// }
// cout << endl;
spfa(t,dis2);
// for(int i = 1; i <= n ; i ++){
// cout << dis2[i] << " ";
// }
// cout << endl;
int num = 0;
// for(int i = 1 ; i <= n ; i ++){
// for(int j = 1; j <= n ; j ++){
// cout << book[i][j] << " ";
// }
// cout << endl;
// }
for(int i = 1; i <= n ; i++){
for(int j = i + 1; j <= n ; j ++){
if(book[i][j] == 0){
if(dis1[i]+1+dis2[j] >= dis1[t] && dis2[i]!=inf &&dis1[j]+1+dis2[i] >= dis1[t])
num ++;
}
}
}
cout << num << endl;
}