Fight Against Traffic
题意:有一个无向图有n个点m条边,且边权为1,给你s和t,现在要你加一条边,使得s和t之间的最短路径不变。问有多少条这种路径。
思路:从s和t两点分别做一次最短路,然后遍历没有相连的两点,判断相连后是否影响最短路。
#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#include <algorithm>
#include <functional>
#define inf 1000000000
using namespace std;
typedef long long ll;
const int MAXN=1e9+10;
const int MAX=1e3+10;
const double eps=1e-6;
int dis1[MAX],dis2[MAX],cnt[MAX];
int n,m,a,b;
vector<int>G[MAX];
bool book[MAX][MAX],vis[MAX];
void init(){
memset(cnt,0,sizeof(cnt));
memset(vis,0,sizeof(vis));
}
int spfa(int s,int t,int dis[]){
queue<int>q;
fill(dis,dis+n+1,inf);
dis[s]=0;
q.push(s);
vis[s]=1;cnt[s]++;
while(q.size()){
int u=q.front();
q.pop();
vis[u]=0;
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(dis[v]>dis[u]+1){
dis[v]=dis[u]+1;
if(!vis[v]){
vis[v]=1;
q.push(v);
cnt[v]++;
if(cnt[v]>n) return -1;
}
}
}
}
return dis[t];
}
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("in.txt","r",stdin);
#endif
init();
cin>>n>>m>>a>>b;
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
book[v][u]=book[u][v]=1;
}
int ans=0;
int sum=spfa(a,b,dis1);
spfa(b,a,dis2);
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(!book[i][j]){
if(min((dis1[i]+dis2[j]),(dis1[j]+dis2[i]))+1>=sum)
ans++;
}
}
}
cout<<ans<<endl;
return 0;
}