1. 程式人生 > 實用技巧 >Dijkstra 鏈式前向星存圖 模板

Dijkstra 鏈式前向星存圖 模板

Dijkstra 鏈式前向星存圖

Luogu P4779

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long int ll;
const int maxn = 10000005;

ll n, m, s, tot, x;
ll dis[maxn], head[maxn];
bool vis[maxn];
priority_queue <pair <ll, ll> > q;

struct node
{
	ll nxt, to, w;
}t[maxn];

void add (const int u,const int v,const int w)
{
	t[++tot].to = v;
	t[tot].w = w;
	t[tot].nxt = head[u];
	head[u] = tot;
}

void dijkstra()
{
	memset (dis, 0x3f3f3f3f, sizeof (dis));  	//初始邊無限大
	memset (vis, 0, sizeof (vis));		//結點初始均為訪問 
	dis[s] = 0;	//起點到自己距離為0 
	q.push (make_pair (0, s));	//起點進隊 
	while (q.size() != 0)
	{
		x = q.top().second;
		q.pop();	//初始結點入隊  
		if (vis[x])  
			continue;	//如果走過,直接跳過 
		vis[x] = 1;	//標記已訪問 
		for (ll i = head[x]; i!=-1; i = t[i].nxt)
		{
			ll y = t[i].to, z = t[i].w;
			if (dis[y] > dis[x] + z)
			{
				dis[y] = dis[x] + z;	//更新起點到y最短路 
				q.push (make_pair (-dis[y], y));	//d[y]相反數入隊,轉小根隊
			}
		}
	}
}

int main()
{
	int t;
	scanf ("%lld %lld %lld %d", &n, &m, &s, &t);
	for(int i=1;i<=n;++i)
	head[i]=-1;
	for (int i = 1; i <= m; i++)
	{
		ll a, b, c;
		scanf ("%lld %lld %lld", &a, &b, &c);
		add (a, b, c);
		add (b, a, c);
	}
	dijkstra();
//	for (int i = 1; i <= n; i++)
//	{
//		printf ("%lld\n", dis[i]);
//	}
	printf("%lld",dis[t]);
	return 0;
}