最短路 CF954D Fight Against Traffic
阿新 • • 發佈:2018-11-05
CF954D Fight Against Traffic
題意描述:
給你一張無向圖,一共有n個點(2 <= n <= 1000),由m條邊連線起來(1 <= m <= 10000),現在要在任意一對沒有連邊的點之間連上一條邊,並且保證s到t之間的最短路徑長度不變(最短路徑長度表示s到t最少經過的邊的數量)(1 <= s,t <= n , s≠t),請你求出一共有多少條這樣的邊。
被水題成功報復。。。
code:
#include <iostream> #include <cstdio> #include <queue> #include <cstring> using namespace std; inline int read(){ int sum=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();} return sum*f; } const int wx=2017; int head[wx],dis1[wx],dis2[wx]; int vis[wx],fl[wx][wx]; int num,n,m,s,t,ans; struct e{ int nxt,to,dis; }edge[wx*2]; void add(int from,int to,int dis){ edge[++num].nxt=head[from]; edge[num].to=to; edge[num].dis=dis; head[from]=num; } struct node{ int u,d; friend bool operator < (const node & a,const node & b){ return a.d>b.d; } }; priority_queue<node > q; void Dij(int S,int dis[]){ for(int i=1;i<=n;i++)dis[i]=0x3f3f3f3f,vis[i]=0; dis[S]=0; q.push((node){S,0}); while(q.size()){ int u=q.top().u; q.pop(); if(vis[u])continue; vis[u]=1; for(int i=head[u];i;i=edge[i].nxt){ int v=edge[i].to; if(dis[v]>dis[u]+edge[i].dis){ dis[v]=dis[u]+edge[i].dis; q.push((node){v,dis[v]}); } } } } int main(){ n=read(); m=read(); s=read(); t=read(); for(int i=1;i<=m;i++){ int x,y; x=read(); y=read(); add(x,y,1); add(y,x,1); fl[x][y]=1; fl[y][x]=1; } Dij(s,dis1); Dij(t,dis2); for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++){ if(fl[i][j])continue; int tmp1=dis1[i]+dis2[j]+1; int tmp2=dis1[j]+dis2[i]+1; if(min(tmp1,tmp2)>=dis1[t])ans++; } } printf("%d\n",ans); return 0; }