CodeForces 954D
阿新 • • 發佈:2019-01-29
給定一個無向圖和起點、終點
現在要向圖中新增邊,使得起點和終點之間的距離不會被縮小
兩遍spfa處理出每個點分別距離起點和終點的最短的距離,雙重迴圈判斷如果dis(起點,i)+dis(j,終點)+1>dis(起點,終點),那麼sum++;
因為點可能會倒過來所以要判斷兩次,詳見程式碼
#include<iostream> #include<cstdio> #include<vector> #include<set> #include<map> #include<string.h> #include<cmath> #include<algorithm> #include<queue> #include<stack> #define LL long long #define mod 1000000007 #define inf 0x3f3f3f3f #define sqr(a) (a)*(a) #define lan(a,b) memset(a,b,sizeof(a)) using namespace std; int tu[1010][1010];//鄰接矩陣 int dis1[1010];//單源最短路徑長度 int dis2[1010]; int n;//點數 bool spfa(int s,int dis[1010]) { queue<int> run; run.push(s); dis[s]=0; while(!run.empty()) { int tem=run.front(); run.pop(); for(int i=1;i<=n;i++) { int p=tu[tem][i]; if(p==inf) continue; if(dis[i]>dis[tem]+p) { run.push(i); dis[i]=dis[tem]+p; } } } return true; } int main() { int m,s,t; while(~scanf("%d%d%d%d",&n,&m,&s,&t)) { lan(tu,inf); lan(dis1,inf); lan(dis2,inf); for(int i=1;i<=m;i++) { int p,q; scanf("%d%d",&p,&q); tu[p][q]=tu[q][p]=1; } spfa(s,dis1); spfa(t,dis2); int sum=0; for(int i=1;i<=n;i++) for(int j=1;j<=n&&j!=i;j++) { if(i==t&&j==s) continue; if(dis1[i]+1+dis2[j]>=dis1[t]&&dis1[j]+1+dis2[i]>=dis1[t]&&tu[i][j]==inf)///判斷兩次 sum++; } printf("%d\n",sum); } return 0; }