hdu 3191 次短路+优先队列 如果让我说:我只能说,实力决定一切

来源:互联网 发布:高维数据统计分析 编辑:程序博客网 时间:2024/04/30 12:10

思路:①我们把每条边的信息放到node中,然后添边和更新

            ②当找到比当前最短路还小的权值时,要更新次短路和最短路,在这里要判断一下,当前最短路是不是在之前已经出现过,如果没有出现则不更新次短路只更新最短路。否则两个都更新

           ③如果当前找到的最短路和已经查找到的最短路相同时,这是只要记录最短路的条数就可以

           ④如果当前找到的值在最短路和次短路之间,那么只需要更新次短路

           ⑤如果当前找的值和次短路相同那么次短路的条数更新

      

#include<iostream>#include<cstdio>#include<algorithm>#include<string.h>#include<queue>#include<vector>#define inf 1<<30using namespace std;const int maxn=55;struct Edge{    int to;    int w;};struct node{    int v,dist,mark;    bool friend operator <(const node &a,const node &b)    {        if(a.dist!=b.dist)           return a.dist>b.dist;        return a.v>b.v;    }};int dis[maxn][3];int dp[maxn][3];int vis[maxn][3];priority_queue<node>Q;vector<Edge>gra[maxn];int N,M,S,E;void init(){    for(int i=0;i<maxn;i++)    {        dis[i][1]=dis[i][2]=inf;       // dp[i][1]=dp[i][2]=0;      //  vis[i][1]=vis[i][2]=0;    }    //用for()循环 15毫秒    //memset() 0毫秒    memset(dp,0,sizeof(dp));    memset(vis,0,sizeof(vis));}void Dijstra(int s,int e){    node p,q,tem;    dp[s][1]=1;    dis[s][1]=0;    q.dist=0;    q.mark=1;    q.v=s;    Q.push(q);    while(!Q.empty())    {        p=Q.top();        Q.pop();        if(vis[p.v][p.mark])//判断一个点是不是 被访问过           continue;        vis[p.v][p.mark]=1;        for(int i=0;i<gra[p.v].size();i++)        {            int vv=gra[p.v][i].to;            int ww=gra[p.v][i].w;            if(!vis[vv][1]&&dis[vv][1]>p.dist+ww)//如果可以判断为最短路            {                if(dis[vv][1]!=inf)//如果在之前的状态中已经找到了一条最短路                {                     dis[vv][2]=dis[vv][1];                     dp[vv][2]=dp[vv][1];                     q.mark=2;                     q.dist=dis[vv][2];                     q.v=vv;                     Q.push(q);                }                dis[vv][1]=p.dist+ww;                dp[vv][1]=dp[p.v][p.mark];                q.mark=1;                q.dist=dis[vv][1];                q.v=vv;                Q.push(q);            }            else if(!vis[vv][1]&&dis[vv][1]==p.dist+ww)            {                dp[vv][1]+=dp[p.v][p.mark];            }            else if(!vis[vv][2]&&dis[vv][2]>p.dist+ww)            {                dis[vv][2]=p.dist+ww;                dp[vv][2]=dp[p.v][p.mark];                q.mark=2;                q.dist=dis[vv][2];                q.v=vv;                Q.push(q);            }            else if(!vis[vv][2]&&dis[vv][2]==p.dist+ww)            {                dp[vv][2]+=dp[p.v][p.mark];            }        }    }}int main(){    int n1,n2,n3;    Edge tem;    while(scanf("%d%d%d%d",&N,&M,&S,&E)!=EOF)    {        for(int i=0;i<maxn;i++)          gra[i].clear();        init();        for(int i=0;i<M;i++)        {            scanf("%d%d%d",&n1,&n2,&n3);            tem.to=n2;            tem.w=n3;            gra[n1].push_back(tem);        }        Dijstra(S,E);        printf("%d %d\n",dis[E][2],dp[E][2]);    }    return 0;}

原创粉丝点击