zoukankan      html  css  js  c++  java
  • 最短路计数——Dijkstra

    题目:

      给出一个N个顶点M条边的无向无权图,顶点编号为1N。问从顶点1开始,到其他每个点的最短路有几条。

                                                  ——传送门

    受到题解的启发,用 Dijkstra A掉(手工代码)

    思路:

      1.无向无权图,建图的时候别忘记建来回的有向边

      2.无权,那么边长建成1就好了

      3.最短路采用 Dijkstra(堆优化)来做,计数操作改装进去,tot[1]=1;用 Dijkstra 更新边长的时候如果大于号(具体见代码)就覆盖,相等的话就加上。

    AC代码:

    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<deque>
    #include<set>
    #include<map>
    #include<vector>
    #include<fstream>
    using namespace std;
    #define maxn 2000005
    #define mod 100003
    int head[maxn],vis[maxn],d[maxn],tot[maxn];
    int cnt=0,n,m,s;
    priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
    struct hh
    {
        int nex,to;
    }t[maxn<<1];
    inline void add(int nex,int to)
    {
        t[++cnt].nex=head[nex];
        t[cnt].to=to;
        head[nex]=cnt;
    }
    inline int read()
    {
        char kr=0;
        char ls;
        for(;ls>'9'||ls<'0';kr=ls,ls=getchar());
        int xs=0;
        for(;ls>='0'&&ls<='9';ls=getchar())
        {
            xs=xs*10+ls-48;
        }
        if(kr=='-') xs=0-xs;
        return xs;
    }
    inline void dijkstra()
    {
        memset(d,0x3f,sizeof(d));
        memset(tot,0,sizeof(tot));
        memset(vis,0,sizeof(vis));
        q.push(make_pair(0,1));
        d[1]=0;
        vis[1]=1;
        tot[1]=1;
        while(!q.empty())
        {
            int u=q.top().second;
            q.pop();
            vis[u]=0;
            for(int v=head[u];v;v=t[v].nex)
            {
                if(d[t[v].to]>d[u]+1)
                {
                    d[t[v].to]=d[u]+1;
                    tot[t[v].to]=tot[u];
                    if(!vis[v])
                    {
                        q.push(make_pair(d[t[v].to],t[v].to));    
                        vis[v]=1;                
                    }
                    continue;
                }
                else if(d[t[v].to]==d[u]+1)
                {
                    tot[t[v].to]+=tot[u];//tot记录的是点上的数,不是边上。(查了好久) 
                    tot[t[v].to]%=mod;
                    continue;
                }//关键是这两个 if 语句,其它的跟单源最短路没什么区别 
            }
        }
    }
    int main()
    {
        n=read();m=read();
        int x,y;
        for(int i=1;i<=m;i++)
        {
            x=read();y=read();
            add(x,y);
            add(y,x);
        }
        dijkstra();
        for(int i=1;i<=n;i++)
        {
            printf("%d
    ",tot[i]);
        }
    return 0;
    }
  • 相关阅读:
    Python动态展示遗传算法求解TSP旅行商问题
    MOEAD算法中均匀权向量的实现---Python
    HDU 5294 多校第一场1007题 最短路+最小割
    POJ 3261 Milk Patterns sa+二分
    HDU 4292 FOOD 2012 ACM/ICPC Asia Regional Chengdu Online
    CodeForces 201A Clear Symmetry
    POJ 1679 The Unique MST 确定MST是否唯一
    POJ 3268 Silver Cow Party 最短路 基础题
    POJ 2139 SIx Degrees of Cowvin Bacon 最短路 水題
    POJ2229 Sumsets 基礎DP
  • 原文地址:https://www.cnblogs.com/lck-lck/p/9614951.html
Copyright © 2011-2022 走看看