题意:有n个点个m条双向边,现在给出两个点S和T并要增加一条边,问增加一条边且S和T之间距离不变短的情况有几种?
题解:首先dfs求一下S到其他点和T到其他点的最短路(好久不写有点手生@。@),然后遍历所有的建边的情况,假设在i和j两个点之间建边则要满足 ds[i] + 1 + dt[j] > ds[T] && ds[j] + 1 + dt[i] > ds[T]。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAX_N = 1e3+9; 4 const int INF = 1e9+9; 5 int N,M,S,T; 6 vector<int> dir[MAX_N]; 7 int vec1[MAX_N],vec2[MAX_N]; 8 void bfs(int pos , int* vec){ 9 fill(vec,vec+MAX_N,INF); 10 queue<int> que; 11 que.push(pos); 12 vec[pos] = 0; 13 while(!que.empty()){ 14 int t = que.front(); 15 que.pop(); 16 for(int i=0;i<dir[t].size();i++){ 17 int x = dir[t][i]; 18 if(vec[x] > vec[t] + 1){ 19 vec[x] = vec[t] + 1; 20 que.push(x); 21 } 22 } 23 } 24 //for(int i=1;i<5;i++)cout<<"!!"<<vec[i]<<endl; 25 } 26 int main(){ 27 while(cin>>N>>M>>S>>T){ 28 for(int i=0;i<MAX_N;i++){ 29 dir[i].clear(); 30 } 31 for(int i=0;i<M;i++){ 32 int a,b; 33 scanf("%d%d",&a,&b); 34 dir[a].push_back(b); 35 dir[b].push_back(a); 36 } 37 bfs(S,vec1); 38 bfs(T,vec2); 39 int ans =0 ; 40 int dis = vec1[T]; 41 for(int i=1;i<=N;i++){ 42 for(int j=i+1;j<=N;j++){ 43 if(vec1[i] + vec2[j] + 1 >= dis && vec1[j] + vec2[i] + 1 >= dis){ 44 ans ++; 45 } 46 } 47 } 48 cout<<ans-M<<endl; 49 } 50 return 0; 51 }