• 题目分享F 三代目


    题意:给你一个有向图,可能有重边,让你求从s到t最短路的条数,如果次短路的长度比最短路的长度多1,那么在加上次短路的条数。

    分析:

    这题挺硬核的,就是顺便再记录一下起点到每个节点的次短路以及最短路与次短路的方案数,真心没啥好说的,代码肯定能看懂

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    
    const int maxn=1e3+1;
    const int maxm=1e4+1;
    const int inf=0x3f3f3f3f;
    
    struct Node
    {
        int to,next,val;
    }e[maxm];
    struct px
    {
        int p,x,val;
        px(){}
        px(int P,int X,int VAL){p=P,x=X,val=VAL;}
        friend bool operator < (const px &x,const px &y)
        {
            return x.val>y.val;
        }
    };
    int head[maxn];
    bool vis[maxn<<1];
    int dis[maxn][2];
    int num[maxn][2];
    int cnt;
    
    void add(int x,int y,int z)
    {
        e[++cnt].to=y;
        e[cnt].next=head[x];
        e[cnt].val=z;
        head[x]=cnt;
    }
    
    int spfa(int s,int f)
    {
        memset(dis,0x3f,sizeof(dis));
        memset(num,0,sizeof(num));
        memset(vis,0,sizeof(vis));
        dis[s][0]=0,num[s][0]=1;
        priority_queue<px> q;q.push(px(0,s,0));
        while(!q.empty())
        {
            px now=q.top();q.pop();
            if(vis[now.x<<1|now.p]) continue;
            vis[now.x<<1|now.p]=1;
            for(int i=head[now.x];i;i=e[i].next)
            {
                int v=e[i].to,val=e[i].val;
                int nowval=now.val+val;
                int nownum=num[now.x][now.p];
                if(nowval<dis[v][0])
                {
                    dis[v][1]=dis[v][0],num[v][1]=num[v][0];
                    dis[v][0]=nowval,num[v][0]=nownum;
                    q.push(px(1,v,dis[v][1]));
                    q.push(px(0,v,nowval));
                }
                else if(nowval==dis[v][0]) num[v][0]+=nownum;
                else if(nowval<dis[v][1])
                {
                    dis[v][1]=nowval,num[v][1]=nownum;
                    q.push(px(1,v,nowval));
                }
                else if(nowval==dis[v][1]) num[v][1]+=nownum;
            }
        }
        if(dis[f][0]==dis[f][1]-1) return num[f][0]+num[f][1];
        else return num[f][0];
    }
    
    int main()
    {
        int t,n,m,x,y,z;
        scanf("%d",&t);
        while(t--)
        {
            memset(head,0,sizeof(head));cnt=0;
            scanf("%d%d",&n,&m);
            while(m--)
            {
                scanf("%d%d%d",&x,&y,&z);
                add(x,y,z);
            }
            scanf("%d%d",&x,&y);
            printf("%d
    ",spfa(x,y));
        }
        return 0;
    }
  • 相关阅读:
    希望多年以后的自己不再如此迷茫
    【转载】撒旦(Satan 4.2)勒索病毒最新变种加解密分析
    java单例模式
    关于double/float 两种基本类型精度丢失的总结
    关于ecplise中一些很实用的技巧
    安装SQL Server和卸载SQL Server步骤
    我进入部门的第一周
    mysql数据库在Linux和windows下免安装实现以及框架开发碰到的问题
    jenkins发布docker到mesos
    u盘作为git仓库,完成不同地方的代码同步
  • 原文地址:https://www.cnblogs.com/lin4xu/p/12951642.html
Copyright © 2020-2023  润新知