dij的链式前向星-模版

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#define INF 0x3f3f3f3f
#define NINF -INF-1
#define ll long long
#define pi acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define lson rt<<1
#define rson rt<<1|1
const ll MAXN=2e6+7;
const ll mod=1e9+7;
using namespace std;
struct edge
{
    int u,v,w;
}edges[10000000];
struct Dijkstra
{
    int n,m;                    // 点数和边数
    int head[MAXN];             // 每个节点出发的边编号(从0开始编号)
    int idx;                     //边的编号
    int d[MAXN];                // s到各个点的距离
    int p[MAXN];                // p[i]表示最短路径树中到达i点的边的边数
    int point[MAXN];
    void init(int n)
    {
        this->n=n;
        mem(head,-1);
        mem(p,0);
		idx=0;
        mem(point,0);
        point[2] = 1;
    }
    void addedge(int u,int v,int w)
    {
        edges[idx].u=head[u];             //表示当前边的储存位置
        edges[idx].v=v;
        edges[idx].w=w;
        head[u]=idx++;
    }
    void dijkstra(int s)
    {
    	typedef pair<int,int>pii;
   		priority_queue<pii,vector<pii>,greater<pii> >q; 
        for(int i=0;i<=n;i++)
d[i]=INF;   				//注意初始起点
        d[s]=0;
        p[s]=1;
        q.push(pii(0,s));				//d[i]位置和s相反,是因为pair函数的问题
        while(!q.empty())
        {
            pii x=q.top();q.pop();
            int u=x.second;
            if(d[u]!=x.first)
                continue;
            for(int i=head[u];i!=-1;i=edges[i].u)
            {
                edge& e=edges[i];
                if(d[e.v]==d[u]+e.w)
                    p[e.v]=(p[e.v]+p[u])%mod;
                else if(d[e.v]>d[u]+e.w)
                {
                    d[e.v]=d[u]+e.w;
                    p[e.v]=p[u];
                    q.push(pii(d[e.v],e.v));
                }
            }
        }
    }
    int dfs(int s)
    {
        if(point[s]>0)
            return point[s];
        for(int i=head[s];i!=-1;i=edges[i].u)
        {
        	edge& e=edges[i];
            if(d[s]>d[e.v])
                point[s]+=dfs(e.v);
        }
        return point[s];
    }
}di;
int main()
{
    int n,m;
    while(scanf("%d",&n)&&n)
    {
        scanf("%d",&m);
        di.init(n);
        for(int i=1;i<=m;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            di.addedge(u,v,w);
            di.addedge(v,u,w);
        }
        di.dijkstra(2);
        printf("%d\n",di.dfs(1));
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-lyslyslys

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值