Description
给出一个带权无向图,包含n个点,m条边。求出s,e的最短路。保证最短路存在。
Input
多组输入。
对于每组数据。
第一行输入n,m(1<= n && n<=510^5,1 <= m && m <= 310^6)。
接下来m行,每行三个整数,u,v,w,表示u,v之间有一条权值为w(w >= 0)的边。
最后输入s,e。
Output
对于每组数据输出一个整数代表答案。
Sample
Input
3 1
1 2 3
1 2
Output
3
提示:这个题目娇羞的很,稍微不注意就A不了,我反反复复试了好多遍…
因为题目给的n很大,也就是图中的点的数量多,然后不适合用二维数组存图。
我用了Bellman-Ford算法和队列优化的Bellman-Ford算法
当然,队列数组的大小开的小的话,他会提示超时,过大的话程序直接无法运行…
#include <bits/stdc++.h>
using namespace std;
int dis[500010],u[7000010],v[7000010],w[7000010];
int main()
{
int inf=99999999;
int i,k,n,m,s,t,check,l,a,b,c;
scanf("%d %d",&n,&m);
l=1;
for(i=1; i<=m; i++)
{
scanf("%d %d %d",&a,&b,&c);
u[l]=a,v[l]=b,w[l]=c;
l++;
u[l]=b,v[l]=a,w[l]=c;
l++;
}
m=2*m;
for(i=1; i<=n; i++)
dis[i]=inf;
scanf("%d %d",&s,&t);
dis[s]=0;
for(k=1; k<n; k++)
{
check=1;
for(i=1; i<=m; i++)
{
if(dis[v[i]]>dis[u[i]]+w[i])
{
dis[v[i]]=dis[u[i]]+w[i];
check=0;
}
}
if(check)
break;
}
printf("%d\n",dis[t]);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int dis[500010],u[7000010],v[7000010],w[7000010];
int first[5000010],next[5000010],book[500010];
int que[50001000];
int main()
{
int inf=99999999;
int i,k,n,m,s,t,l,a,b,c,head,tail;
while(scanf("%d %d",&n,&m)!=EOF)
{
for(i=1; i<=n; i++)
{
first[i]=-1;
book[i]=0;
dis[i]=inf;
}
l=1;
for(i=1; i<=m; i++)
{
scanf("%d %d %d",&a,&b,&c);
u[l]=a,v[l]=b,w[l]=c;
next[l]=first[u[l]];
first[u[l]]=l;
l++;
u[l]=b,v[l]=a,w[l]=c;
next[l]=first[u[l]];
first[u[l]]=l;
l++;
}
m=2*m;
scanf("%d %d",&s,&t);
dis[s]=0;
head=1;
tail=1;
que[tail]=s;
tail++;
book[s]=1;
while(head<tail)
{
k=first[que[head]];
while(k!=-1)
{
if(dis[v[k]]>dis[u[k]]+w[k])
{
dis[v[k]]=dis[u[k]]+w[k];
if(book[v[k]]==0)
{
que[tail]=v[k];
tail++;
book[v[k]]=1;
}
}
k=next[k];
}
book[que[head]]=0;
head++;
}
printf("%d\n",dis[t]);
}
return 0;
}