- 网红重庆1
【问题描述】
网红城市——重庆,堪称一座8D的魔幻大都市,明明(不要问我明明是谁?)在一楼上的电梯,到了11楼出电梯又是一楼。
假设重庆有N个地点,给出各个地点的海拔高度,各个地点之间可能有双向的路径连接,或者单向的路径连接。有一个外地人来重庆,要从地点C到D,但他对爬坡下坎很不习惯,请帮他在从C到D所有路径中,找一条海拔变化(海拔降低或升高都视为正的值)最小的路径,即组成路径的各条直接路径海拔变化的总和最小。
【输入形式】
输入文件包含多个测试数据。每个测试数据第1行是两个整数N和M,N表示地点的数目,5≤N≤50,地点的序号从1开始计起,M表示这N个地点之间直接路径的数目,对任意两个地点A、B,A和B之间有一条双向直接路径、从A到B有一条单向直接路径、从B到A有一条单向直接路径,这3种情形最多只出现一种情形,测试数据保证这N个地点之间是互相可达的(再啷个爬坡下坎,总还是走得到的);第2行有N个整数,表示这N个地点的海拔高度,范围在[100, 1000],可能存在相同海拔高度的地点;接下来有M行,描述了M条直接路径,格式为“1 A B”或“2 A B”,前者表示从地点A到地点B的一条单向直接路径,后者表示地点A和B之间的一条双向直接路径,A和B为地点的序号,A≠B;每个测试数据的最后一行为两个整数C和D,表示那个外地人要从地点C到D,C和D为地点的序号,C≠D。测试数据保证地点序号都是有效的。
输入文件最后一行为0 0,代表输入结束。
【输出形式】
对每个测试数据,输出占一行,为求得的从地点C到D的各条路径中海拔变化总和的最小值。
【样例输入】
5 5
100 160 230 450 120
2 1 2
1 1 5
2 2 5
2 3 4
2 4 5
1 3
0 0
【样例输出】
570
#include<bits/stdc++.h>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 100
struct node
{
int t;
int w;
node*next;
};
queue<int>q;
int n,N;
node*List[MAXN];
int inq[MAXN];
int d[MAXN];
int p[MAXN];
int a[MAXN];//海拔高度
void spfa(int src)
{
int i,u;//u为队列头顶点序号
node*t;
for(i=1;i<=N;i++)
{
d[i]=INF;p[i]=src;inq[i]=0;
}
d[src]=0;p[src]=src;inq[src]++;
q.push(src);
while(!q.empty())
{
u=q.front();q.pop();inq[u]--;
t=List[u];
while(t!=NULL)
{
int v=t->t;
if(d[v]>d[u]+t->w)
{
d[v]=d[u]+t->w;p[v]=u;
if(!inq[v]){q.push(v);inq[v]++;}
}
t=t->next;
}
}
}
int main()
{
int M,i,j,r,C,D;//N个地点,M条路 //从C到D
int u,v;//,w;
node*t;
//memset(List,0,sizeof(List));
while(1)
{
scanf("%d%d",&N,&M);
if(!N)break;
for(i=1;i<=N;i++)scanf("%d",&a[i]);
// cout<<"222"<<endl;
for(j=1;j<=M;j++)
{
scanf("%d%d%d",&r,&u,&v);//输入并生成地图
t=new node;
if(r==1)
{
t->t=v;
t->w=abs(a[v]-a[u]);
t->next=NULL;
if(List[u]==NULL)List[u]=t;
else {t->next=List[u];List[u]=t;}
}
else if(r==2)
{
t->t=v;
t->w=abs(a[v]-a[u]);
t->next=NULL;
if(List[u]==NULL)List[u]=t;
else {t->next=List[u];List[u]=t;}
t=new node;
t->t=u;
t->w=abs(a[v]-a[u]);
t->next=NULL;
if(List[v]==NULL)List[v]=t;
else {t->next=List[v];List[v]=t;}
}
}
scanf("%d %d",&C,&D);
spfa(C);
for(j=1;j<=N;j++)//释放链表空间
{
t=List[j];
while(t)
{
List[j]=t->next;delete t;t=List[j];
}
}
// if(d[D]<1000)
printf("%d\n",d[D]);
// else
//printf("INF\n");
}
return 0;
}