题目
一个有向图,求一点到所有点的最短距离
输入
4 6 1(4个点,6条边,从1出发)
1 2 2(1点到2点有一条权值2的线)
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4
输出
0 2 4 3
解题思路
这题数据非常的大
说明
时空限制:1000ms,128M
数据规模:
对于20%的数据:N<=5,M<=15
对于40%的数据:N<=100,M<=10000
对于70%的数据:N<=1000,M<=100000
对于100%的数据:N<=10000,M<=500000
所以我们用SPFA算法,用邻接表
代码
#include<cstdio>
using namespace std;
struct woc{int next,x,y,w;
};
woc a[500001];//邻接表
int n,m,k,state[10001],ls[10001],t,head,tail,f[10001];
bool v[10001];
int main()
{scanf("%d%d%d",&n,&m,&k);state[1]=k;//第一个点for (int i=1;i<=m;i++){scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);a[i].next=ls[a[i].x];ls[a[i].x]=i;//邻接表}for (int i=1;i<=n;i++) f[i]=2147483647;//初始化head=0;tail=1;v[state[1]]=true;//标记f[k]=0;while (head!=tail)//注意不能是<={head++;//出队head=(head-1)%n+1;//循环队列t=ls[state[head]];//读取边while (t!=0){if (f[a[t].x]+a[t].w<f[a[t].y]){f[a[t].y]=f[a[t].x]+a[t].w;//松弛if (!v[a[t].y]){tail++;//入队tail=(tail-1)%n+1;//循环队列state[tail]=a[t].y;v[a[t].y]=true;//标记}}t=a[t].next;//下一条边}v[state[head]]=false;//解封}f[k]=0;for (int i=1;i<=n;i++)printf("%d ",f[i]);//输出
}