zoukankan      html  css  js  c++  java
  • poj 3463(最短路、次短路计数)

    题意:给出一个有向图、源点、终点,求出源点到终点的最短路径和比最短路径长度大1的路径条数。

    思路:求出最短路径条数和次短路径条数,如果次短路比最短路长度大一,返回最短路径和次短路径的条数和。否则返回最短路径条数。

    实现:dist[i][2]表示点i到源点的两条路径长度,cnt[i][2]表计数,用dijstra的贪心思想对状态进行更新,与求最短路不同的是,次短路也需要入队和更新。

    状态更新如下:

    1.新值小于最短路:更新次短路及计数,更新最短路及计数。(先把次短路更新为最短路状态,然后更新最短路)

    2.新值等于最短路:更新最短路计数。

    3.新值大于最短路,小于次短路:更新次短路及计数。

    4新值等于次短路:更新次短路计数。

    code

    View Code
    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    using namespace std;
    #define M 100010
    #define N 1010
    #define inf 0x3fffffff
    struct edge{
        int to,w,next;
    }e[M];
    int pre[N],dist[N][2],cnt[N][2],b[N][2];
    int cnt0,n,m;
    void add(int a,int b,int w)
    {
        e[cnt0].next=pre[a];
        e[cnt0].to=b;
        e[cnt0].w=w;
        pre[a]=cnt0++;
    }
    struct node{
        int w,u,flag;
        bool operator <(const node &x)const
        {
            return w>x.w;
        }
    };
    int dijstra(int start,int end)
    {
        priority_queue<node> q;
        node in;
        for(int i=1;i<=n;i++){
            dist[i][0]=dist[i][1]=inf;
            cnt[i][0]=cnt[i][1]=0;
            b[i][0]=b[i][1]=0;
        }
        dist[start][0]=0;
        cnt[start][0]=1;
        in.w=0;in.u=start;in.flag=0;
        q.push(in);
        while(!q.empty())
        {
            int u=q.top().u;
            int flag=q.top().flag;
            q.pop();
            if(b[u][flag])continue;
            b[u][flag]=1;
            for(int edg=pre[u];edg!=0;edg=e[edg].next)
            {
                int v=e[edg].to;int w=dist[u][flag]+e[edg].w;
                if(dist[v][0]>w)
                {
                    if(dist[v][0]!=inf)
                    {
                        dist[v][1]=dist[v][0];
                        cnt[v][1]=cnt[v][0];
                        in.w=dist[v][1];
                        in.flag=1;
                        in.u=v;
                        q.push(in);
                    }
                    dist[v][0]=w;
                    cnt[v][0]=cnt[u][flag];
                    in.w=dist[v][0];
                    in.u=v;
                    in.flag=0;
                    q.push(in);
                }
                else if(dist[v][0]==w)
                {
                    cnt[v][0]+=cnt[u][flag];
                }
                else if(dist[v][1]>w)
                {
                    dist[v][1]=w;
                    cnt[v][1]=cnt[u][flag];
                    in.w=dist[v][1];
                    in.flag=1;
                    in.u=v;
                    q.push(in);
                }
                else if(dist[v][1]==w)
                {
                    cnt[v][1]+=cnt[u][flag];
                }
            }
        }
        if(dist[end][0]==dist[end][1]-1)return cnt[end][0]+cnt[end][1];
        else return cnt[end][0];
    }
    int main()
    {
        int ca;
        scanf("%d",&ca);
        while(ca--)
        {
            cnt0=1;
            memset(pre,0,sizeof(pre));
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++)
            {
                int a,b,w;
                scanf("%d%d%d",&a,&b,&w);
                add(a,b,w);
            }
            int start,end;
            scanf("%d%d",&start,&end);
            printf("%d\n",dijstra(start,end));
            //for(int i=1;i<=n;i++)
            //cout<<cnt[i][0]<<":"<<dist[i][0]<<endl;
        }
        return 0;
    }
  • 相关阅读:
    010_STM32CubeMXADC
    009_STM32CubeMXPWM
    008_STM32CubeMX定时器中断
    007_STM32CubeMX外部中断
    006_STM32CubeMX按键输入
    005_STM32CubeMX串口
    004_STM32CubeMX官方例程
    003_STM32CubeMX点灯
    002_STM32CubeMX配置基础工程
    006_word发表博客到博客园中
  • 原文地址:https://www.cnblogs.com/huangriq/p/2468329.html
Copyright © 2011-2022 走看看