spfa算法JDOJ2208短 题解

来源:互联网 发布:基础网络知识 编辑:程序博客网 时间:2024/05/17 02:57

2208: 短


题目描述

给出无向图G=(V,E),求点V1和点VN之间的最短路。

输入

第一行两个整数|V|和|E|。

2~E+1行,每行3个整数Xi,Yi,Wi,表示点Vxi和点Vyi之间存在权值为Wi的边。

输出

一个整数表示最短路的权值。

样例输入

3 3
1 2 1
2 3 1
3 1 1

样例输出

1

提示

对于50%的数据,V<=103

对于100%的数据,V<=105,E<=106,1<=Wi<=2。

此题V<=10^5,E<=10^6,所以有Dij堆优化和spfa两种算法.

今天我写一个spfa算法

#include<stdio.h>
#include<string.h>
int idx;
struct Edge
{
    int val,to,next;
};
Edge edge[2000001];//edge[i].val表示边权是多少,edge[i].to表示到达谁,edge[i].next表示下一个是谁.存双向边数组要开2倍
int head[2000001];
int f[1000001];
int queue[4000001];
bool used[1000001];
void addedge(int a,int b,int c)//链表存边
{
    edge[++idx].next=head[a];
    head[a]=idx;
    edge[idx].to=b;
    edge[idx].val=c;
}
int main()
{
    int n,e,i,j,a,b,c;
    scanf("%d%d",&n,&e);
    for(i=1;i<=e;i++)
    {
        scanf("%d%d%d",&a,&b,&c);
        addedge(a,b,c);
        addedge(b,a,c);//调用函数
    }
    int front=0,tail=0;
    queue[tail++]=1;
    memset(f,1,sizeof(f));
    f[1]=0;
    memset(used,0,sizeof(used));
    used[1]=1;
    while(front<tail)//spfa核心,used[i]表示是否进入队列
    {
        int idx2=queue[front++];
        used[idx2]=0;
        for(j=head[idx2];j;j=edge[j].next)
        {
            if(f[edge[j].to]>f[idx2]+edge[j].val)
            {
                f[edge[j].to]=f[idx2]+edge[j].val;
                if(used[edge[j].to]==0)
                {
                    queue[tail++]=edge[j].to;
                    used[edge[j].to]=1;
                }
           }
        }
    }
    printf("%d",f[n]);
}



原创粉丝点击