链接: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\n",sum);
}
return 0;
}