题目简介:中文题,多读几遍题,清楚题意了就好做了。
题目分析:这道题考察对Dijkstra的熟练运用,本质还是求最短路。
最核心的地方就是对哪些节点可以访问。我们可以进行枚举,设当前我们能够访问的最高等级maxl是lv[i],然后做标记进行Dijkstra,更新ans答案。
if(lv[j]>maxl||maxl-lv[j]>m)//如果两者的等级差距
v[j]=true;//做标记在Dijkstra中不再访问
else
v[j]=false;
如下代码(附带注释)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define MAXN 1000000
using namespace std;
int n,m,lv[110],price[110][110],x[110],d[110];
//price[i][j] 表示在i点j的优惠品价格
bool v[110];
int Dijkstra()
{
for(int i=1;i<=n;i++)
d[i]=price[0][i];//任何点的初始距离设为price[0][i],即为该物品的价格
for(int i=1;i<=n;i++)
{
int pos=0;
int res=100000;
for(int j=1;j<=n;j++)
{
if(!v[j]&&res>d[j])
{
pos=j;
res=d[j];
}
}
if(pos==0)
break;
v[pos]=true;
for(int j=1;j<=n;j++)
{
if(!v[j]&&price[pos][j]>0/*pos点可达*/&&d[j]>d[pos]+price[pos][j])
d[j]=d[pos]+price[pos][j];
}
}
return d[1];
}
int main()
{
memset(d,0,sizeof(d));
memset(lv,0,sizeof(lv));
for(int i=1;i<=n;i++)
d[i]=MAXN;
memset(v,false,sizeof(v));
int ans=0x7ffffff;
cin>>m>>n;
for(int i=1;i<=n;i++)
{
cin>>price[0][i]>>lv[i]>>x[i];
for(int j=1;j<=x[i];j++)
{
int t,u;
cin>>t>>u;
price[t][i]=u;
}
}
int maxl;
int tem;
for(int i=1;i<=n;i++)
{
maxl=lv[i];//设当前访问的最高等级是lv[i]
for(int j=1;j<=n;j++)
{
if(lv[j]>maxl||maxl-lv[j]>m)//如果两者的等级差距
v[j]=true;//做标记在Dijkstra中不再访问
else
v[j]=false;
}
tem=Dijkstra();
if(tem<ans)
ans=tem;
}
cout<<ans<<endl;
while(1);
return 0;
}