题目链接:
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;
}