hdu 3790 最短路径问题 最短路Dijkstra

来源:互联网 发布:学钢琴 软件 编辑:程序博客网 时间:2024/05/17 06:15

做图论的都是上辈子折翼的天使。。。有点难想,但若有明确的思路,程序很好打


清除所有点的标号
设d[0]=0,其他d[i]=INF
循环n次
{
     在所以未标号结点中,选出d值最小的节点x
     标记节点x
   对于从x出发的所有边(x,y), 更新d[y]=min(d[y],d[x]+w(x,y));
}


错了几次
第一次把路程和金钱分开处理了,很快查出来
第二次又错了,但心想这是模板题,怎么错了,一看discuss,重边。。哭了。。
打的时候发现了很多问题
假如INF==1<<31-1
memset(a,INF,sizeof(a)); 初始都为0.。。
而0x1f==31
memset(a,0x1f,sizeof(a))后,初始都为522133279.
memset(a,0x1f1f1f1f,sizeof(a))后,初始都为522133279.
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=1010;const int INF=0x1f1f1f1f;int dislen[maxn];int discost[maxn];int w[maxn][maxn];int ss[maxn][maxn];bool visit[maxn];int n,m;int s,t;int main(){    while(scanf("%d",&n)!=EOF)    {        scanf("%d",&m);        if(n==0&&m==0)            break;        int i,j;        memset(visit,true,sizeof(visit));        memset(w,0x1f,sizeof(w));        memset(ss,0x1f,sizeof(ss));        int u,v,len,cost;      //  for(i=1; i<=n; i++)       // {        //    w[i][i]=0;        //    ss[i][i]=0;       // }       for(i=1;i<n;i++)       {           for(j=1;j<=n;j++)           {               cout<<w[i][j]<<' ';           }           cout<<endl;       }        for(i=0; i<m; i++)        {            scanf("%d%d%d%d",&u,&v,&len,&cost);           if(w[u][v]>len||w[u][v]==len&&ss[u][v]>cost)            {                w[u][v]=len;                w[v][u]=len;                ss[u][v]=cost;                ss[v][u]=cost;            }        }        scanf("%d%d",&s,&t);            for(i=1; i<=n; i++)            {                if(i==s)                {                    dislen[i]=0;                    discost[i]=0;                }                else                {                    dislen[i]=w[s][i];                    discost[i]=ss[s][i];                }            }            for(j=1; j<=n; j++)            {                int x;                int minn=INF;                for(i=1; i<=n; i++)                {                    if(visit[i]==true&&dislen[i]<minn)                    {                        minn=dislen[i];                        x=i;                    }                }                visit[x]=false;                for(i=1; i<=n; i++)                {                    if(visit[i]==true&&dislen[i]>dislen[x]+w[x][i])                    {                        dislen[i]=dislen[x]+w[x][i];                        discost[i]=discost[x]+ss[x][i];                    }                    else if(visit[i]==true&&dislen[i]==dislen[x]+w[x][i]&&ss[x][i]+discost[x]<discost[i])                    {                        discost[i]=discost[x]+ss[x][i];                    }                }            }            printf("%d %d\n",dislen[t],discost[t]);    }    return 0;}

0 0
原创粉丝点击