POJ-1062-昂贵的聘礼
http://poj.org/problem?id=1062
等级差距大于m的两个人不能直接或间接交易,而1必须是图的终点,所以最短路径中所有的点的等级都必须在(level[1]-m,level[1]+m)之间,所以可以枚举等级限制,对每一次枚举求一次最短路
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define INF 99999999
#define N 110
int lev[N],p[N];
int map[N][N];
int vis[N];
int dis[N];
int dijkstra(int cost[][110],int n,int x,int m)
{
int i,j,k,temp;
memset(vis,0,sizeof(vis));
dis[0]=0;
vis[0]=1;
for(i=1;i<n;i++)
dis[i]=cost[0][i];
for(i=1;i<n;i++)
{
temp=INF;
for(j=0;j<n;j++)
{
if(!vis[j]&&dis[j]<temp)
{
temp=dis[j];
k=j;
}
}
if(temp==INF)
break;
vis[k]=1;
for(j=0;j<n;j++)
if(!vis[j]&&dis[j]>dis[k]+cost[k][j]&&lev[k]>=x&&lev[k]<=x+m)
dis[j]=dis[k]+cost[k][j];
}
return dis[1];
}
int main()
{
int m,n;
int i,j,x,price,id,low,ans;
while(scanf("%d%d",&m,&n)!=EOF)
{
for(i=0;i<=100;i++)
{
map[i][i]=0;
for(j=i+1;j<=100;j++)
map[i][j]=map[j][i]=INF;
}
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&p[i],&lev[i],&x);
for(j=1;j<=x;j++)
{
scanf("%d%d",&id,&price);
map[id][i]=price;
}
}
for(i=1;i<=n;i++)
map[0][i]=p[i];
low=lev[1]-m;
ans=INF;
for(i=low;i<=lev[1];i++)
{
int temp=dijkstra(map,n+1,i,m);
if(temp<ans)
ans=temp;
}
printf("%d\n",ans);
}
return 0;
}