cf- Educational Codeforces Round 40 -D
阿新 • • 發佈:2018-03-22
efi code 短路徑 emp brush log urn end cpp
題意:給你n個點,m條邊,一個起點s,一個終點t的無向圖,問在某兩個點之間加一條邊,不改變s到t的最短路徑的值的加法有多少種,所有點一定連接;
思路:首先,默認相鄰兩點的權值都為1,會改變值的情況有:
從s出發,算出s的單源最短路dist,如果dist[x]+1<dist[t];
從t出發,算出t的單源最短路Dist,如果Dist[x]+1<Dist[s];
介於兩點之間,s—t之間的某兩個點之間+1<dist[s],也就是:dist[x]+Dist[y]+1<(Dist[s] | | dist[t]);
所以從s跑一遍,再從t跑一遍最短路,然後遍歷所有點,把能改變值的情況算出來;
#include<iostream> #include<algorithm> #include<cstring> #include<queue> #include<set> #include<cmath> #define maxn 100005 const int inf=99999; using namespace std; struct Edge { int next; int to; int w; }edge[maxn]; struct node { int num; int dist; node(int _num=0,int _dist=0):num(_num),dist(_dist){} friend bool operator<(node a,node b) { return a.dist>b.dist; } }; int head[maxn]; int s[maxn]; int n,m,cnt; int dis[maxn]; int dise[maxn]; int disb[maxn]; int book[1005][1005]; //int book[maxn]; bool vis[maxn]; int be,en; void add(int u,int v,int w) { edge[cnt].next=head[u]; edge[cnt].to=v; edge[cnt].w=w; head[u]=cnt++; } void dij(int x) { priority_queue<node>que; memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[x]=0; que.push(node(x,0)); while(!que.empty()) { node p=que.top(); que.pop(); int now=p.num; if(vis[now]) continue; vis[now]=true; for(int i=head[now];i!=-1;i=edge[i].next) { Edge e=edge[i]; if(dis[e.to]>dis[now]+e.w&&!vis[e.to]) { dis[e.to]=dis[now]+e.w; que.push(node(e.to,dis[e.to])); } } } } int main() { int x,y,w; cin>>n>>m>>be>>en; cnt=0; memset(book,0,sizeof(book)); memset(head,-1,sizeof(head)); for(int i=1;i<=m;i++) { cin>>x>>y; add(x,y,1); add(y,x,1); } int zz=0; int ans=0; for(int i=1;i<=n-1;i++) zz+=i; dij(en); for(int i=1;i<=n;i++) dise[i]=dis[i]; dij(be); for(int i=1;i<=n;i++) disb[i]=dis[i]; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i==j) continue; if(disb[i]+dise[j]+1<dise[be]) { if(book[i][j]==0&&book[j][i]==0) { ans++; } book[i][j]=book[j][i]=1; } else if(disb[j]+1<dise[be]-1) { if(book[j][en]==0&&book[en][j]==0) ans++; book[j][en]=book[en][j]=1; } else if(dise[j]+1<disb[en]) { if(book[be][j]==0&&book[j][en]==0) ans++; book[j][be]=book[be][j]=1; } } } // cout<<ans<<endl; zz-=m; cout<<zz-ans<<endl; return 0; }
---恢復內容結束---
cf- Educational Codeforces Round 40 -D