hdu3191 Dij

题目的意思是找次最短路的条数,这道题只好用dij算法,通过这题可以很好的理解dij。

可以看看大神的思想http://www.cnblogs.com/wally/archive/2013/04/16/3024490.html

但是本题本来不应该用优先队列,是因为hdu的数据库太水。我就用了一个循环找最短的边。没用优先队列

#include <iostream>
using namespace std;
const int N=100;
const int inf=1<<30;
int dis[N][2],step[N][2],head[N],vis[N][2];
struct node
{
    int v,w,next;
}map[N*N];
int n,s,e,tot;
void add(int a,int b,int w)
{
    map[tot].v=b;
    map[tot].w=w;
    map[tot].next=head[a];
    head[a]=tot++;
}
void dij()
{    
    int i,flag;
    dis[s][0]=0;
    step[s][0]=1;
    while(1)
    {
        int min=inf;
        int u;    
        for(i=0;i<n;i++)
        {
            if(!vis[i][0]&&dis[i][0]<min)
            {    
                u=i;
                min=dis[i][0];
                flag=0;
            }else
            if(!vis[i][1]&&dis[i][1]<min)
            {
                min=dis[i][1];
                u=i;
                flag=1;
            }
        }
        if(u==e&&flag==1)break;
        if(min==inf)break;
        vis[u][flag]=1;
        for(i=head[u];i+1;i=map[i].next)
        {
            int v=map[i].v;
            int w=dis[u][flag]+map[i].w;
            if(dis[v][0]>w)
            {
                if(dis[v][0]!=inf)
                {
                    dis[v][1]=dis[v][0];
                    step[v][1]=step[v][0];
                }
                dis[v][0]=w;
                step[v][0]=step[u][flag];
            }else if(dis[v][0]==w)
            {
                step[v][0]+=step[u][flag];
            }else if(dis[v][1]>w)
            {
                dis[v][1]=w;
                step[v][1]=step[u][flag];
            }else if(dis[v][1]==w)
            {
                step[v][1]+=step[u][flag];
            }
        }
    }
    
}
void init()
{
    for(int i=0;i<=n;i++)
    {
        head[i]=-1;
        dis[i][1]=dis[i][0]=inf;
        step[i][1]=step[i][0]=0;
        vis[i][1]=vis[i][0]=0;
    }
    tot=0; 
}
int main()
{
    int m,a,b,i,w;
    while(scanf("%d%d%d%d",&n,&m,&s,&e)!=EOF)
    {
        init();
        for( i=0;i<m;i++)
        {
            scanf("%d%d%d",&a,&b,&w);
            add(a,b,w);
        }
        dij();
        printf("%d %d\n",dis[e][1],step[e][1]);
    }
    return 0;
}

 

 

posted on 2013-08-09 16:01  黎昊明  阅读(413)  评论(0编辑  收藏  举报

导航