• 【洛谷 1144】最短路计数


    题目描述

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

    输入格式

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

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

    输出格式

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

    输入输出样例

    输入 #1
    5 7
    1 2
    1 3
    2 4
    3 4
    2 3
    4 5
    4 5
    
    输出 #1
    1
    1
    1
    2
    4
    

    说明/提示

    11到55的最短路有44条,分别为22条1-2-4-51245和22条1-3-4-51345(由于4-545的边有22条)。

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

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

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

    题解:又是一道最短路计数恩 ,好像比上一个版本要更好哦

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N=1000001;
    const int mod=100003;
    const int oo=0x3f3f3f3f;
    int cnt,head[N],yxr=oo,B,E,P;
    struct node{
        int to,next;
    }e[N*2];
    void add(int u,int v){
        e[++cnt].to=v; 
        e[cnt].next=head[u];
        head[u]=cnt;
    }
    int vis[N],dis[N],ans[N],n,m,u,v;
    queue<int>q;
    void SPFA(int s){
        memset(dis,0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        vis[s]=1; dis[s]=0; q.push(s);
        int x,v; ans[1]=1;
        while(!q.empty()){
            x=q.front(); q.pop(); vis[x]=0;
            for(int i=head[x];i;i=e[i].next){
                v=e[i].to;
                if(dis[v]>dis[x]+1){
                    dis[v]=dis[x]+1;
                    ans[v]=ans[x];
                    if(!vis[v]) { q.push(v); vis[v]=1; }
                }
                else if(dis[v]==dis[x]+1)
                        { ans[v]+=ans[x]; ans[v]%=mod; }
                //if(dis[v]>dis[x]+1){
                //    dis[v]=dis[x]+1;
                //    if(!vis[v]) { vis[v]=1; q.push(v); }
                //} 
            }
        }
    }
    
    int main(){
        scanf("%d %d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d %d",&u,&v);
            add(u,v); add(v,u);
        }
        SPFA(1); 
        for(int i=1;i<=n;i++)
            printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    Windows API 中 OVERLAPPED 结构体 初始化
    QString 转换成 wchar 的一个小陷阱
    Windows VHD Create, Attach, 获得Disk序号
    Programmatically mount a Microsoft Virtual Hard Drive (VHD)
    chcp437 转换英语,在西班牙语系统中无效
    Windows 版本 Enterprise、Ultimate、Home、Professional
    openssl 查看证书
    Ubuntu 搜索文件
    微软的 Sysinternals 系统管理工具包,例如可找出自动启动的流氓软件
    HTML 表格实例
  • 原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11722175.html
Copyright © 2020-2023  润新知