题目链接:邮递员
思路:先正向存边,求出最短路后再反向建边,再跑一遍最短路即可!
#include<iostream> #include<cstdio> #include<cstring> #include<bits/stdc++.h> using namespace std; const int N = 520000; const int maxn = 1200; struct Node{ int ne; int to; int w; }e[N<<1]; int head[maxn],dis[maxn]; int n,m,x[N],y[N],val[N],cnt; bool vis[maxn]; void init() { memset(head,-1,sizeof(head)); memset(dis,0x7f,sizeof(dis)); memset(vis,0,sizeof(vis)); cnt = 0; } void add(int u,int v,int val) { e[cnt].to = v; e[cnt].ne = head[u]; e[cnt].w = val; head[u] = cnt ++; } void SPFA(int k) { queue<int>q; q.push(k); dis[k] = 0; vis[k] = 1; while(!q.empty()) { int now = q.front(); q.pop(); for(int i= head[now];~i;i=e[i].ne) { int to = e[i].to; if(dis[to] > dis[now] + e[i].w) { dis[to] = dis[now] + e[i].w; if(!vis[to]) { q.push(to); vis[to] = 1; } } } vis[now] = 0; } } int main() { scanf("%d%d",&n,&m); init(); for(int i=1;i<=m;i++) { scanf("%d%d%d",&x[i],&y[i],&val[i]); add(x[i],y[i],val[i]); } SPFA(1); int sum = 0; for(int i=1;i<=n;i++) { sum += dis[i]; } memset(e,0,sizeof(e)); init(); for(int i=1;i<=m;i++) { add(y[i],x[i],val[i]); } for(int i=2;i<=n;i++) { SPFA(1); sum += dis[i]; } printf("%d\n",sum); return 0; }