hdoj-1874 暢通工程續【最短路徑--dijkstra&&floyd&&spfa】

題目:http://acm.hdu.edu.cn/showproblem.php?pid=1874

本題需要注意的地方是

起點終點並不是第一個 最後一個 是另外給定的

如果不存在從S到T的路線,就輸出-1    說明S和T之間無道路連通  T到S的距離(即dis[t])爲INF

 

dijkstra:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 222
#define INF 0x3f3f3f3f
using namespace std;
int n,m,dis[maxn],map[maxn][maxn];
bool visit[maxn];

void dijkstra(int start)
{
    int i,j,next;
    memset(visit,0,sizeof(visit));//初始化 
    for(i=0;i<n;i++)
        dis[i]=map[start][i];//dis[]表示i到start的距離  main()中已對map[][]初始化 這裏初始化dis=INF 
    visit[start]=true;
    dis[start]=0;
    for(i=1;i<n;i++)
    {
        int temp=INF;
        for(j=0;j<n;j++)
        {
            if(!visit[j]&&dis[j]<temp)
            {
                temp=dis[j];
                next=j;
            }
        }
        visit[next]=true;
        for(j=0;j<n;j++)
        {
            if(!visit[j])
                dis[j]=min(dis[j],dis[next]+map[next][j]);
        }
    }
}

int main()
{
    int a,b,x,s,t,i,j;
    while(~scanf("%d%d",&n,&m))
    {
        memset(map,INF,sizeof(map));//或者下面註釋的9行 
//        for(i=0;i<n;i++)
//        {
//            for(j=0;j<n;j++)
//            {
//                if(i==j)
//                    map[i][j]=0;
//                else map[i][j]=INF;
//            }
//        }
        while(m--)
        {
            scanf("%d%d%d",&a,&b,&x);
            if(map[a][b]>x)
                map[a][b]=map[b][a]=x;
        }
        scanf("%d%d",&s,&t);
        dijkstra(s);
        if(dis[t]==INF)
            printf("-1\n");
        else printf("%d\n",dis[t]);
    }
}

floyd:

三個for循環

#include<stdio.h>
#define INF 0x3f3f3f3f
int n,m,path[220][220];
void floyd()
{
    int i,j,k;
    for(k=0;k<n;k++)
        for(i=0;i<n;i++)
            for(j=0;j<n;j++)
            {
                if(path[i][j]>path[i][k]+path[k][j])
                    path[i][j]=path[i][k]+path[k][j];        
            }
}

void init()
{
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        {
            if(i==j)
                path[i][j]=0;
            else path[i][j]=INF;
        }
}

void getmap()
{
    int a,b,x;
    while(m--)
    {
        scanf("%d%d%d",&a,&b,&x);
        if(path[a][b]>x)
            path[a][b]=path[b][a]=x;
    }
}

int main()
{
    int s,t;
    while(~scanf("%d%d",&n,&m))
    {
        init();
        getmap();
        floyd();
        scanf("%d%d",&s,&t);
        if(path[s][t]<INF)
            printf("%d\n",path[s][t]);
        else printf("-1\n");
    }
    return 0;
}

spfa:

#include<cstdio>
#include<cstring>
#include<queue>
#define INF 0x3f3f3f3f
#define MAXN 200+20//點數 
#define MAXM 2000+20//邊數 
using namespace std;
int n,m,top,vis[MAXN],dis[MAXN],head[MAXN];

struct node {
 int from,to,val,next;
};
node edge[MAXM];

void init()//初始化鄰接表 
{
 top=0;//建表從零開始
 memset(head,-1,sizeof(head));
}

void add(int u,int v,int w)//建立鄰接表   
{
// edge[top].from=u;
// edge[top].to=v;
// edge[top].val=w;
// edge[top].next=head[u];
// head[u]=top++;
 node E={u,v,w,head[u]};
 edge[top]=E;
 head[u]=top++;
}

void spfa(int s,int e)//s爲源點
{
 queue<int>q;//存儲每次入隊的點
 memset(vis,0,sizeof(vis));
 memset(dis,INF,sizeof(dis));//存儲源點 到這個點的最短路
 vis[s]=1;//表示這個點是否在隊列裏面
 dis[s]=0;
 q.push(s);
 while(!q.empty())
 {
  int u=q.front();
  q.pop();
  vis[u]=0;//該點之後還可能進入隊列    消除標記  
  for(int i=head[u];i!=-1;i=edge[i].next)//遍歷以u爲起點的 所有邊
  {
   int v=edge[i].to;
   if(dis[v]>dis[u]+edge[i].val)
   {
    dis[v]=dis[u]+edge[i].val;
    if(!vis[v])
    {
     q.push(v);
     vis[v]=1;
    }
   }
  }
 }
 if(dis[e]==INF)
  printf("-1\n");
 else 
  printf("%d\n",dis[e]);
}

void getmap()
{
 int a,b,x;
 while(m--)
 { 
  scanf("%d%d%d",&a,&b,&x);
  add(a,b,x);
  add(b,a,x);//無向圖  既可由a->b,也可由b->a; 
 }
}

int main()
{
 while(~scanf("%d%d",&n,&m))//n|m位運算符  n==0&&m==0時輸入結束 
 {
  int start,end;
  init();
  getmap();
  scanf("%d%d",&start,&end);
  spfa(start,end);
 }
 return 0;
}



 

發佈了52 篇原創文章 · 獲贊 10 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章