• 最短路计数


    链接:

    这是个真的签到题...

    经过一个寒暑假的洗礼

    相信你们对图论,提升了很大的兴趣

    那么这题我直接就扔给你作为一个签到题

    好了,你只需要找一个最短路有几条即可。

    不会吧不会吧,不会真有人觉得是最短路计数叭

    CCoolGuang当然要给你们上条件的

    给出一个起点SS,一个终点TT,你要求出从STS→T是最短路的情况下,最大边权不超过WW的路径有多少条

    答案对1e9+71e9+7取余

    Input

    第一行:n,m,S,T,Wn,m,S,T,W

    接下来mm行分别为:x,y,wx,y,w,代表xyww是一条边权为ww的有向边

    Output

    按照题目输出

    Samples

    Input Copy
    4 5 1 4 2
    1 2 3
    2 4 1
    3 2 2
    1 3 1
    3 4 3
    Output
    1

    Hint

    n50000n≤50000,m100000m≤100000

    对于第一个样例的解释:

    #pragma GCC optimize(1)
    #pragma GCC optimize(2)
    #pragma GCC optimize(3,"Ofast","inline")
    #include<cstring>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<bits/stdc++.h> 
    using namespace std;
    typedef long long ll;
    template <typename Tp>
    void read(Tp &x){//read(n);
        x=0;char ch=1;int fh;
        while(ch!='-'&&(ch>'9'||ch<'0')){
            ch=getchar();
        }
        if(ch=='-'){
            fh=-1;ch=getchar();
        }else fh=1;
        while(ch>='0'&&ch<='9'){
            x=(x<<1)+(x<<3)+ch-'0';ch=getchar();
        }
        x*=fh;
    }
    inline char read1()//字符串读入挂
    {
        register char ch=getchar();
        while(ch<'A'||ch>'M')ch=getchar();
        return ch; 
    }
    const int maxn=1e6+100;
    int head[maxn],d[maxn],ans[maxn];
    int vis[maxn];
    int n,m,s,t,W;
    struct node{
        int to;
        int next;
        int w;
    }edge[maxn];
    int cnt=0;
    void add(int u,int v,int w){
        edge[++cnt].w=w;
        edge[cnt].to=v;
        edge[cnt].next=head[u];
        head[u]=cnt;
    }
    void spfa(){
        memset(d,0x3f3f3f,sizeof d);
        queue<int>q;
        d[s]=0;//起点 
        vis[s]=1;
        ans[s]=1;// 本身为1个最短路 
        q.push(s);
        while(q.size()){
            int x=q.front();q.pop();
            vis[x]=0;
            for(int i=head[x];i;i=edge[i].next){
                int y=edge[i].to;
                if(d[y]>d[x]+edge[i].w){//如果满足u到v的距离比原本到v的距离小,则更新
                    d[y]=d[x]+edge[i].w;
                    ans[y]=ans[x];// x点和y点在一条路上,所以y的最短路个数等于x的最短路个数
                    if(!vis[y]){
                        q.push(y);
                        vis[y]=1;
                    }
                }
                else if(d[y]==d[x]+edge[i].w){
                    ans[y]+=ans[x];// 该点最短路个数为y最短路个数+x最短路个数
    //                ans[y]%=mod;
                }
            } 
        }
        
    }
    int main(){
        cin>>n>>m>>s>>t>>W;
        ll a,b,z;
        for(int i=1;i<=m;i++){
            read(a),read(b),read(z);
            if(z>W){
                continue;
            }
            add(a,b,z);
        }
        spfa();
        cout<<ans[t]<<endl;
        
    } 

    例二:

    洛谷:P1144 最短路计数 

    题目描述

    给出一个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。

    //#pragma GCC optimize(1)
    //#pragma GCC optimize(2)
    //#pragma GCC optimize(3,"Ofast","inline")
    #include<cstring>
    #include<cstdio>
    #include<iostream>
    #include<queue> 
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    template <typename Tp>
    void read(Tp &x){//read(n);
        x=0;char ch=1;int fh;
        while(ch!='-'&&(ch>'9'||ch<'0')){
            ch=getchar();
        }
        if(ch=='-'){
            fh=-1;ch=getchar();
        }else fh=1;
        while(ch>='0'&&ch<='9'){
            x=(x<<1)+(x<<3)+ch-'0';ch=getchar();
        }
        x*=fh;
    }
    inline char read1()//字符串读入挂
    {
        register char ch=getchar();
        while(ch<'A'||ch>'M')ch=getchar();
        return ch; 
    }
    const int maxn=1e6+100;
    const int mod=100003; 
    int head[maxn],d[maxn],ans[maxn];
    int vis[maxn];
    int n,m,s,t,W;
    struct node{
        int to;
        int next;
        int w;
    }edge[maxn];
    int cnt=0;
    void add(int u,int v,int w){
        edge[++cnt].w=w;
        edge[cnt].to=v;
        edge[cnt].next=head[u];
        head[u]=cnt;
    }
    void spfa(){
        memset(d,0x3f3f3f,sizeof d);
        queue<int>q;
        d[s]=0;//起点 
        vis[s]=1;
        ans[s]=1;// 本身为1个最短路 
        q.push(s);
        while(q.size()){
            int x=q.front();q.pop();
            vis[x]=0;
            for(int i=head[x];i;i=edge[i].next){
                int y=edge[i].to;
                if(d[y]>d[x]+edge[i].w){//如果满足u到v的距离比原本到v的距离小,则更新
                    d[y]=d[x]+edge[i].w;
                    ans[y]=ans[x];// x点和y点在一条路上,所以y的最短路个数等于x的最短路个数
                    if(!vis[y]){
                        q.push(y);
                        vis[y]=1;
                    }
                }
                else if(d[y]==d[x]+edge[i].w){
                    ans[y]+=ans[x];// 该点最短路个数为y最短路个数+x最短路个数
                    ans[y]%=mod;
                }
            } 
        }
        
    }
    int main(){
        cin>>n>>m;
        s=1;//起点 
        for(int i=1;i<=m;i++){
            int a,b;
            read(a),read(b);
            add(a,b,1);
            add(b,a,1);
        }
        spfa();
        for(int i=1;i<=n;i++){
            cout<<ans[i]<<endl;
        } 
        
    } 
  • 相关阅读:
    android四大组件--ContentProvider具体解释
    C语言指针的初始化和赋值
    微信游戏《全民炫舞》公司的引擎开发和布料系统技术介绍
    Struts2自己定义拦截器实例—登陆权限验证
    数据仓库与数据挖掘的一些基本概念
    acm省赛选拔组队赛经验谈
    【我所认知的BIOS】—&gt; uEFI AHCI Driver(5) — 第一个protocol最终要開始安装了
    ios项目开发(天气预报项目):使用正则获取 weather.com.cn站点信息
    每日总结-05-16(再见强哥有感)
    编程算法基础-2.7作业-通讯编码-格式检查
  • 原文地址:https://www.cnblogs.com/lipu123/p/13746780.html
Copyright © 2020-2023  润新知