链接:https://vjudge.net/problem/POJ-1511#author=scu2017
题意:
B208的小姐姐们想去学校各地宣传ACM,但是让小姐姐们跑太远的路总是不太好的,因此麻烦G学长帮小姐姐们计算一下,小姐姐们到各地宣传再回到B208的最短路径总和是多少。
已知:学校一共有n个宣传点,B208是标号为1的点。剩下n-1个点每个点各派1位小姐姐,询问每个小姐姐到达宣传点再回到B208的最短路径和是多少。
思路:
数据很大,我用邻接表+优先队列优化写的。
因为第一次用优先队列优化,队列初始化搞错了。WA了2个小时。。。
代码:
#include <iostream> #include <memory.h> #include <string> #include <istream> #include <sstream> #include <vector> #include <stack> #include <algorithm> #include <map> #include <queue> using namespace std; const int MAXN = 1000009; const long long INF = 1000000000; typedef long long LL; //邻接表存图优化Dijkstra算法 struct Node { int _w; long long _v; bool operator < (const Node & that)const { return this->_v > that._v; } Node(int w,int v):_w(w),_v(v){} }; int First[MAXN],Next[MAXN]; int u[MAXN],v[MAXN],w[MAXN]; LL Dis[MAXN]; int Vis[MAXN]; int n,m; void Read_Graph() { scanf("%d%d",&n,&m); for (int e = 1;e <= m;e++) { scanf("%d%d%d",&u[e],&v[e],&w[e]); } } void Init() { for (int i = 1;i<=m;i++) First[i] = -1; for (int e = 1;e <= m;e++) { Next[e] = First[u[e]]; First[u[e]] = e; } } void Swap() { for (int e = 1;e <= m;e++) { int t = u[e]; u[e] = v[e]; v[e] = t; } } void Dijkstra() { for (int i = 1;i <= n;i++) { Dis[i] = INF; Vis[i] = 0; } Dis[1] = 0; priority_queue<Node> que; que.push(Node(1,0)); while (!que.empty()) { if (Vis[que.top()._w] == 1) que.pop(); else { int e = que.top()._w; Vis[e] = 1; e = First[e]; while (e != -1) { long long tmp = Dis[u[e]] + w[e]; if (Vis[v[e]] != 1&&Dis[v[e]] > tmp) { Dis[v[e]] = tmp; que.push(Node(v[e],Dis[v[e]])); } e = Next[e]; } que.pop(); } } } int main() { int t; scanf("%d",&t); while (t--) { long long sum = 0; Read_Graph(); Init(); Dijkstra(); for (int i = 1;i<=n;i++) sum += Dis[i]; Swap(); Init(); Dijkstra(); for (int i = 1;i<=n;i++) sum += Dis[i]; printf("%lld ",sum); } return 0; }