1003 Emergency (25 分)(求最短路径)
给出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; }