思路:单源最短路问题,用dijkstra算法。注意题目中的等级限制意思是假如m为1,酋长的等级为2,那么如果你和等级3的交易后就不能和等级1的人交易,因此要枚举每次的等级范围。
#include <iostream>
#include <cstdio>
#include <cstring>
#define INF 9999999
using namespace std;
struct Object
{
int price,level,succedaneum_num;
}object[105];
int m,n;
int graph[105][105],dis[105],min_statue,max_statue;
bool used[105],can_trade[105];
void dijkstra(int v)
{
int i,j,u,min;
memset(used,false,sizeof(used));
memset(can_trade,true,sizeof(can_trade));
for (i=1;i<=n;i++)
{
dis[i]=graph[v][i];
if (object[i].level<min_statue || object[i].level>max_statue)
can_trade[i]=false;
}
used[v]=true;
for (i=1;i<n;i++)
{
min=INF;
u=v;
for (j=1;j<=n;j++)
if (can_trade[j] && used[j]==false && dis[j]<min)
{
min=dis[j];
u=j;
}
used[u]=true;
for (j=1;j<=n;j++)
if (can_trade[j] && used[j]==false && dis[u]+graph[u][j]<dis[j])
dis[j]=dis[u]+graph[u][j];
}
}
int main(int argc, char** argv)
{
int i,j,ans,v,e,tmp_ans;
while (scanf("%d%d",&m,&n)==2)
{
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
graph[i][j]=INF;
for (i=1;i<=n;i++)
{
graph[i][i]=0;
scanf("%d%d%d",&object[i].price,&object[i].level,&object[i].succedaneum_num);
for (j=0;j<object[i].succedaneum_num;j++)
{
scanf("%d%d",&v,&e);
graph[i][v]=e;
}
}
ans=INF;
for (i=0;i<=m;i++)
{
min_statue=object[1].level-m+i;
max_statue=object[1].level+i;
dijkstra(1);
for (j=1,tmp_ans=INF;j<=n;j++)
if (can_trade[j])
tmp_ans=min(tmp_ans,dis[j]+object[j].price);
ans=min(tmp_ans,ans);
}
printf("%d\n",ans);
}
return 0;
}