1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pii pair<int,int> 4 #define mp make_pair 5 #define inf 0x3f3f3f3f 6 const int maxn=10005; 7 vector<pii>g[maxn]; 8 int N,M,d[maxn],f[maxn]; 9 bool vis[maxn]; 10 int dij(){ 11 memset(vis,0,sizeof(vis)); 12 memset(d,inf,sizeof(d)); 13 memset(f,inf,sizeof(f)); 14 priority_queue<pii,vector<pii>,greater<pii> >q; 15 d[1]=0; 16 f[1]=0; 17 q.push(mp(0,1)); 18 while(!q.empty()){ 19 int u=q.top().second;q.pop(); 20 if(vis[u])continue; 21 vis[u]=1; 22 for(int i=0;i<g[u].size();++i){ 23 int v=g[u][i].first,w=g[u][i].second; 24 if(d[v]>d[u]+w){ 25 d[v]=d[u]+w; 26 f[v]=w; 27 q.push(mp(d[v],v)); 28 }else if(d[v]==d[u]+w && f[v]>w){ 29 f[v]=w; 30 } 31 } 32 } 33 34 int ans=0; 35 for(int i=2;i<=N;++i)ans+=f[i]; 36 return ans; 37 } 38 int main(){ 39 int a,b,c; 40 cin>>N>>M; 41 while(M--){ 42 cin>>a>>b>>c; 43 g[a].push_back(mp(b,c)); 44 g[b].push_back(mp(a,c)); 45 } 46 cout<<dij()<<endl; 47 return 0; 48 }
dij求解最短路的过程可以看作在生成一颗树,源点就是根,如果最短路恰好都只有唯一的一条的话那就正好是一颗
树了,考虑到最短路可能有多种情况,就相当于树上的一个环,破环的过程就是选择其中一条过来的路径,在本题里
最优解显然就是选择过来的那条边最短的那条路径(是在已经是最短路径的前提下)。稍微改下dij算法就好了。
原文:https://www.cnblogs.com/zzqc/p/12376995.html