其实这一道题还是比较不错的
这一道题的题意稍微转化一下就是邮递员要到一个节点 然后再返回 求最短路
这我们很显然是可以用dijkstra算法的
我们先按照题目中给的边(单向边) 跑一边最短路
接下来一步我们是要求从各个点出发到S的最短路
乍一看很复杂的样子
其实只需要把整张图的边全部倒过来存储 然后再从起点开始跑一边最短路就可以了!
下面是代码(其实敲起来还是很简单的 练练代码熟练度~)
#include<bits/stdc++.h> #define pa pair<int,int> #define maxn 1005 using namespace std; vector<int> v[maxn],w[maxn]; vector<int> v2[maxn],w2[maxn]; int n,m ; int vis[maxn]; int dis[maxn]; void dijkstra(){ priority_queue<pa,vector<pa> ,greater<pa> > q; q.push(make_pair(0,1)); memset(dis,0x3f,sizeof(dis)); dis[1]=0; while(!q.empty()) { int x=q.top().second; q.pop(); if(vis[x]) continue; vis[x]=1; for(int i=0;i<v[x].size();i++) { int y=v[x][i]; int val=w[x][i]; if(dis[x]+val<dis[y]) { dis[y]=dis[x]+val; q.push(make_pair(dis[y],y)); } } } } void dijkstra2() { priority_queue<pa,vector<pa>,greater<pa> > q; q.push(make_pair(0,1)); memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); dis[1]=0; while(!q.empty()) { int x=q.top().second; q.pop(); if(vis[x]) continue; vis[x]=1; for(int i=0;i<v2[x].size();i++) { int y=v2[x][i]; int val=w2[x][i]; if(dis[x]+val<dis[y]) { dis[y]=dis[x]+val; q.push(make_pair(dis[y],y)); } } } } int main() { scanf("%d%d",&n,&m); for(int i=1,x,y,z;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); v[x].push_back(y); w[x].push_back(z); v2[y].push_back(x); w2[y].push_back(z); } long long ans=0; dijkstra(); for(int i=2;i<=n;i++) ans+=dis[i]; dijkstra2(); for(int i=2;i<=n;i++) ans+=dis[i]; printf("%lld",ans); return 0; }
原文地址:https://www.cnblogs.com/akioi/p/12215570.html
时间: 2024-10-12 04:44:22