【HDU 2544 最短路】

来源:互联网 发布:java网络高级编程 编辑:程序博客网 时间:2024/05/17 08:11

最短路

Problem Description
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?

Input
输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
输入保证至少存在1条商店到赛场的路线。

Output
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间

Sample Input
2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0

Sample Output
3
2

附上 floyd , dijkstra 和 spfa邻接表 三种算法 :

floyd :
缺点 :时间复杂度高O(N^3);

优点 : 求出了所有点两两间的最短距离 ;

dijkstra :

缺点 : 只能求出一点到其余各点的最短距离;

优点 : 时间复杂度低O(N^2);

spfa邻接表 :

两点间的关系都可以有临界表处理,时间复杂度较低;
可以处理开不了二维数组的大数据;

根据实际情况,做最佳选择

floyd :

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int INF=0x3f3f3f3f;int mapp[110][110];int N,M;void floyd(){    int i,j,l;    for(l=1;l<=N;l++)    {        for(i=1;i<=N;i++)        {            if(mapp[i][l]==INF)                continue;            for(j=1;j<=N;j++)            {                mapp[i][j]=min(mapp[i][j],mapp[i][l]+mapp[l][j]);//更新 i ,j 两点间的最短距离            }        }    }    printf("%d\n",mapp[1][N]);}int main(){    int i,j;    int a,b,c;    while(scanf("%d%d",&N,&M)!=EOF)    {        if(N==0&&M==0)            break;        for(i=1;i<=N;i++)        {            mapp[i][i]=0;            for(j=1;j<i;j++)                mapp[i][j]=mapp[j][i]=INF;        }        while(M--)        {            scanf("%d%d%d",&a,&b,&c);            if(mapp[a][b]>c)//判断是否有重边                mapp[a][b]=mapp[b][a]=c;        }        floyd();    }    return 0;}

dijkstra :

#include<cstdio>#include<cstring>const int INF=0x3f3f3f3f;int mapp[110][110];int vis[110];//标记点int dis[110];int N,M;void dijkstra(){    int i,j;    int ml;    int ans;//记录最小距离    memset(vis,0,sizeof(vis));//初始化标记    for(i=1;i<=N;i++)        dis[i]=mapp[1][i];//当前所有的点到商店的最短距离    vis[1]=1;//标记 1 点    for(i=2;i<=N;i++)    {        ans=INF;        for(j=1;j<=N;j++)        {            if(vis[j]==0&&ans>dis[j])            {                ans=dis[j];//记录小到 i 点的最短距离                ml=j;//记录小到 i 点的距离最短的点            }        }        vis[ml]=1;//把该点标记        for(j=1;j<=N;j++)        {            if(vis[j]==0&&dis[ml]+mapp[ml][j]<dis[j])                dis[j]=dis[ml]+mapp[ml][j];//更新到 1 点的最短距离        }    }    printf("%d\n",dis[N]);//输出赛场到商店的最短距离}int main(){    int i,j;    int a,b,c;    while(scanf("%d%d",&N,&M)!=EOF)    {        if(N==0&&M==0)            break;            for(i=1;i<=N;i++)            {                mapp[i][i]=0;              for(j=1;j<i;j++)                mapp[i][j]=mapp[j][i]=INF;            }            for(i=1;i<=M;i++)            {                scanf("%d%d%d",&a,&b,&c);                if(mapp[a][b]>c)//建议养成习惯加上可能会有重边的的情况                    mapp[a][b]=mapp[b][a]=c;            }            dijkstra();    }    return 0;}

spfa邻接表 :

#include<cstdio>#include<algorithm>#include<queue>#include<cstring>using namespace std;const int INF=0x3f3f3f3f;struct node{    int to,val,next;}st[10011];int head[110];int dis[110];int vis[110];int num;int N,M;void init()//初始化{    num=0;    memset(head,-1,sizeof(head));    memset(vis,0,sizeof(vis));}void  add(int x,int y,int z){    st[num].to=y;    st[num].val=z;    st[num].next=head[x];    head[x]=num++;}/*void add(int x,int y,int z)//同上面的效果一样,两种临界表的建立方式{    node E={y,z,head[x]};    st[num]=E;    head[x]=num++;}*/void spfa(){    queue <int> q;    while(!q.empty())        q.pop();    int i,j;   fill(dis+1,dis+N+1,INF);    dis[1]=0;    q.push(1);    vis[1]=1;//标记    while(!q.empty())    {        int  w=q.front();        q.pop();        vis[w]=0;//释放        for(i=head[w];i!=-1;i=st[i].next)        {            int ml=st[i].to;//遍历以 w 为起点的所有边的终点 ml            if(dis[ml]>dis[w]+st[i].val)            {                dis[ml]=dis[w]+st[i].val;            if(!vis[ml])//优化 不会有多余的点进队列            {                vis[ml]=1;                q.push(ml);            }            }        }    }    printf("%d\n",dis[N]);//1到N的最短距离}int main(){    int a,b,c;    while(scanf("%d%d",&N,&M)!=EOF)    {        if(N==0&&M==0)            break;            init();        while(M--)        {            scanf("%d%d%d",&a,&b,&c);            add(a,b,c);//建立临界表            add(b,a,c);        }        spfa();    }    return 0;}
0 0
原创粉丝点击