最短路 hdu4522 湫湫系列故事——过年回家

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4522

题目意思:

求出从已知起点到已知终点,两种方式的最小不舒服度。

注意如果某条路为1的话,既可以选硬座又可以选卧铺。

解题思路:

迪杰斯特拉算法。

代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<list>
#include<queue>
#include<ctype.h>
#define eps 1e-6
#define INF (1<<30)
#define PI acos(-1.0)
using namespace std;

#define Maxn 207
bool edge[Maxn][Maxn][2]; //edge[i][j][0]表示i和j之间可以坐硬座,1表示可以做卧铺
int vis[Maxn][2],dis[Maxn][2],A[2];
char save[10000+7];
int n;

void dijs(int start,int kind)
{
   memset(vis,false,sizeof(vis));
   for(int i=1;i<=n;i++)
   {
      if(edge[start][i][kind])
         dis[i][kind]=A[kind];
      else
         dis[i][kind]=INF;
   }
   dis[start][kind]=0;
   vis[start][kind]=true;
   for(int i=1;i<=n-1;i++)
   {
      int Min=INF,flag;

      for(int j=1;j<=n;j++)
      {
         if(vis[j][kind]==false)
         {
            if(dis[j][kind]<Min)
            {
               Min=dis[j][kind];
               flag=j;
            }
         }
      }
      if(Min==INF)
            return ;
      vis[flag][kind]=true;
      for(int k=1;k<=n;k++)
      {
         if(vis[k][kind])
            continue;
         if(edge[flag][k][kind]&&A[kind]+Min<dis[k][kind])
            dis[k][kind]=A[kind]+Min;
      }

   }
}

int main()
{
   int q,t,k,start,end;

   scanf("%d",&q);
   while(q--)
   {
      scanf("%d%d",&n,&t);
      memset(edge,false,sizeof(edge));
      for(int j=1;j<=t;j++)
      {
         scanf("%s%d",save,&k);
         int len=strlen(save);
         save[len++]='\0';
         int last=0,cur=0;

         int i=0;
         for(;save[i]!='+';i++)
            last=last*10+save[i]-'0';
         for(i++;i<len;i++)
         {
            if(!isdigit(save[i]))
            {
               edge[last][cur][k]=true;
               if(k)
                  edge[last][cur][0]=true;
               last=cur;
               //printf("%d\n",cur);
               cur=0;
            }
            else
               cur=cur*10+save[i]-'0';
         }
      }
      scanf("%d%d",&A[0],&A[1]);
      scanf("%d%d",&start,&end);
      dijs(start,0); //硬座的情况
      dijs(start,1);//卧铺的情况
      int ans=min(dis[end][0],dis[end][1]);

      if(ans==INF)
         printf("-1\n");
      else
         printf("%d\n",ans);


      }

   return 0;
}


原文地址:https://www.cnblogs.com/javawebsoa/p/3080524.html