1003 Emergency (25 分)(求最短路徑)
阿新 • • 發佈:2018-12-07
給出N個城市,m條無向邊。每個城市中都有一定數目的救援小組,所有邊的邊權已知。現在給出起點和終點,求從起點到終點的最短路徑條數及最短經上的救緩小組數目只和。如果有多條最短路徑,則輸出數目只和最大的
Dijkstra 做法
#include<bits/stdc++.h> using namespace std; int n,m,s,u; const int N=1000; const int inf=0x3f3f3f3f; int mp[N][N]; int dis[N]; bool vis[N]; int value[N]; int num[N]; int w[N]; void Dijkstra() { fill(vis,vis+N,false); fill(dis,dis+N,inf); fill(w,w+N,0); fill(num,num+N,0); num[s]=1;//賦值 w[s]=value[s];//賦值 for(int i=0;i<n;i++) dis[i]=mp[s][i]; dis[s]=0; for(int i=0;i<n-1;i++){ int u=-1; int minn=inf; for(int j=0;j<n;j++){ if(!vis[j]&&dis[j]<minn){ u=j; minn=dis[j]; } } if(u==-1) return; vis[u]=true; for(int j=0;j<n;j++){ if(!vis[j]&&dis[u]+mp[u][j]<=dis[j]){ if(mp[u][j]+dis[u]<dis[j]){ dis[j]=mp[u][j]+dis[u]; num[j]=num[u]; w[j]=w[u]+value[j]; } else{ num[j]+=num[u]; if(w[u]+value[j]>w[j]){ w[j]=w[u]+value[j]; } } } } } } int main() { scanf("%d %d %d %d",&n,&m,&s,&u); for(int i=0;i<n;i++) scanf("%d",&value[i]); memset(mp,inf,sizeof(mp)); while(m--){ int a,b,c; scanf("%d %d %d",&a,&b,&c); mp[a][b]=mp[b][a]=c; } Dijkstra(); printf("%d %d",num[u],w[u]); return 0; }
spfa做法
#include<bits/stdc++.h> using namespace std; int n,m,s,v; struct node { int to; int dis; node(int _to=0,int _dis=0):to(_to),dis(_dis){} }; const int N=1010; int dis[N]; bool vis[N]; int w[N]; int num[N]; int value[N]; vector<node>mp[N]; set<int>st[N]; const int inf=0x3f3f3f3f; void spfa() { fill(dis,dis+N,inf); fill(vis,vis+N,false); fill(w,w+N,0); w[s]=value[s]; num[s]=1; queue<int>Q; Q.push(s); vis[s]=true; dis[s]=0; while(!Q.empty()){ int u=Q.front(); Q.pop(); vis[u]=false; for(int i=0;i<mp[u].size();i++){ int to=mp[u][i].to; int diss=mp[u][i].dis; if(diss+dis[u]<dis[to]){ dis[to]=diss+dis[u]; w[to]=w[u]+value[to]; num[to]=num[u]; st[to].clear(); st[to].insert(u); if(!vis[to]){ Q.push(to); vis[to]=true; } } else if(diss+dis[u]==dis[to]){ if(w[to]<w[u]+value[to]){ w[to]=w[u]+value[to]; } st[to].insert(u); num[to]=0;//因為spfa會重複到一個點 所以可能重複的邊 for(set<int>::iterator it=st[to].begin();it!=st[to].end();++it){ num[to]+=num[*it]; } if(!vis[to]){ Q.push(to); vis[to]=true; } } } } } int main() { scanf("%d %d %d %d",&n,&m,&s,&v); for(int i=0;i<n;i++) scanf("%d",&value[i]); for(int i=0;i<n;i++) mp[i].clear(); while(m--){ int a,b,c; scanf("%d %d %d",&a,&b,&c); mp[a].push_back(node(b,c)); mp[b].push_back(node(a,c)); } spfa(); printf("%d %d\n",num[v],w[v]); return 0; }