一開始我以爲只是把原本dijsktra的模板改一下就行了
同學來問我原本覺得很簡單,但是自己打卻一直過不去點,答案不對了
然後發現似乎需要更大的改動?
用鄰接表,直接while循環k點,先更新k點的最短路,再找到路最短的點更新k,進行下一次的循環
用鄰接矩陣,則先找到路最短的點,然後再更新點的最短路,然後進行下一次的循環
(我太難了我只能這麼死記硬背了QwQ)
記住稀疏圖用鄰接表
稠密圖用鄰接矩陣!
#include <cstdio>
#include <iostream>
using namespace std;
struct CZP
{
int next,to,dis;
}a[10000001];
int n,m,s,b[10000001],h[1000001],top;
long long dis[10000001];
void cun(int from,int to,int dis)
{
a[++top].next=h[from];
a[top].to=to;
a[top].dis=dis;
h[from]=top;
}
int main()
{
scanf("%d%d%d",&n,&m,&s);
for (int i=1;i<=n;i++)
h[i]=-1;
for (int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
cun(x,y,z);
}
for (int i=1;i<=n;i++)
dis[i]=2147483647;
dis[s]=0;
int k=s;
while (b[k]==0)
{
b[k]=1;
int v=h[k]; //不需要先找出最小值,直接每次大循環循環找到的當前最短路最小的點
while (v!=-1)
{
if (!b[a[v].to] && dis[a[v].to]>dis[k]+a[v].dis)
dis[a[v].to]=dis[k]+a[v].dis;
v=a[v].next;
} //一開始就直接更新點的最短路
long long minn=2147483647;
for (int i=1;i<=n;i++)
if ((!b[i]) && (minn>dis[i]))
{
minn=dis[i];
k=i; //找到下一個最短路的點
}
}
for (int i=1;i<=n;i++)
printf("%lld ",dis[i]);
return 0;
}