zoukankan      html  css  js  c++  java
  • luogu P1144 最短路计数

    题目描述

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

    输入输出格式

    输入格式:

    输入第一行包含2个正整数N,M,为图的顶点数与边数。

    接下来M行,每行两个正整数x, y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边。

    输出格式:

    输出包括N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出mod 100003后的结果即可。如果无法到达顶点i则输出0。

    输入输出样例

    输入样例#1:
    5 7
    1 2
    1 3
    2 4
    3 4
    2 3
    4 5
    4 5
    
    输出样例#1:
    1
    1
    1
    2
    4
    

    说明

    1到5的最短路有4条,分别为2条1-2-4-5和2条1-3-4-5(由于4-5的边有2条)。

    对于20%的数据,N ≤ 100;

    对于60%的数据,N ≤ 1000;

    对于100%的数据,N<=1000000,M<=2000000。

    跑小改的spfa

    对于某个点i,一条到达他的最短路径,必须经过一个和i直接相连而且最短路长度比i小1的点x。、

    下面是丑陋的代码

    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    
    queue<int>que;
    const int N=200002;
    const int mod=100003;
    int dis[N];
    int n,m;
    int head[N];
    int count[N];
    int vis[N];
    struct node{
        int l,next;
    }edge[N*2];
    
    int num=0;
    void add_edge(int x,int y)
    {
        edge[num].l=y;
        edge[num].next=head[x];
        head[x]=num++;
    }
    
    void spfa()
    {
        que.push(1);
        count[1]=1;
        dis[1]=1;
        vis[1]=1;
        while(!que.empty())
        {
            int k=que.front();
            que.pop();
            for(int i=head[k];i!=-1;i=edge[i].next)
            {
                int q=edge[i].l;
                if(dis[k]+1<dis[q])
                {
                    dis[q]=dis[k]+1;
                    count[q]=count[k]%mod;
                    if(!vis[q])
                    {
                        vis[q]=1;
                        que.push(q);
                    }
                }
                else if(dis[k]+1==dis[q])
                count[q]=(count[q]+count[k])%mod;
            }
            vis[k]=0;
        }
        for(int i=1;i<=n;i++)
        printf("%d
    ",count[i]);
    }
    
    int main()
    {
        memset(dis,1,sizeof(dis));
        memset(head,-1,sizeof head);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            add_edge(a,b);
            add_edge(b,a);
        }
        spfa();
        return 0;
    }
  • 相关阅读:
    CF997C Sky Full of Stars
    LOJ6160 二分图染色
    AT4996 [AGC034F] RNG and XOR
    AT4119 [ARC096C] Everything on It
    20200701线性代数概率期望练习
    SNOI2020 LOJ3326 字符串
    SNOI2020 LOJ3323 生成树
    SNOI2020 LOJ3324 取石子
    Gym-102576A Bags of Candies
    Gym-102576H Lighthouses
  • 原文地址:https://www.cnblogs.com/sssy/p/6874103.html
Copyright © 2011-2022 走看看