题目
思路
dij+优先队列+前向星
代码
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
#define MAXX 200005
#define INF 0x3f3f3f3f
using namespace std;
struct Edge
{
int to, dis, next;
} e[MAXX];
int head[MAXX], vis[MAXX];
int cnt, n, m, s;
long long dist[MAXX]; //这里的数组要开ll,否则会wa
struct Node
{
int id;
long long dis; //这里跟着记录,所以要一起
bool operator<(const Node &a) const
{ return a.dis < dis; }
};
void add(int from, int to, int dis)
{
e[++cnt].to = to;
e[cnt].dis = dis;
e[cnt].next = head[from];
head[from] = cnt;
}
void dijstra()
{
priority_queue<Node> pq;
pq.push(Node{s, 0});
dist[s] = 0;
while (!pq.empty())
{
Node n1 = pq.top();
pq.pop();
int tmp = n1.id;
if (vis[tmp])
continue;
vis[tmp] = 1;
for (int i = head[tmp]; i; i = e[i].next)
{
int j = e[i].to;
if ( e[i].dis + dist[tmp] < dist[j])
{
dist[j] = e[i].dis + dist[tmp]; //dist开longlong,可能是数据会溢出
pq.push(Node{j, dist[j]});
}
}
}
}
int main()
{
while (cin >> n >> m >> s)
{
cnt = 0;
memset(head, 0, sizeof head);
memset(vis, 0, sizeof vis);
memset(dist, INF, sizeof dist);//在这里一定记得初始化成最大的!!
for (int i = 0; i < m; ++i)
{
int from, to, dis;
//cin >> from >> to >> dis;
scanf("%d%d%d", &from, &to, &dis);//数据比较大,用scanf,否则会超时
add(from, to, dis);
}
dijstra();
for (int i = 1; i <n; ++i)
{
cout << dist[i] << ' ';
}
cout << dist[n] << endl;
}
return 0;
}
注意
优先队列+结构体的时候,重载运算符的写法
bool operator<(const Node &a) const
{ return a.dis < dis; }