[POJ1062]昂贵的聘礼
- 【题目大意】现有n个物品,每个物品价格为vi,同时可以用其他物品减免价格(当然,你必须拥有该物品).问如何购买可以使得到物品1的花费最少.此外,还有附加等级限制(详见题目).
- 实质上是dijkstra.(虽然题目很绕).
- 以物品1的等级为基准,限定范围来进行多次dij.这样所得方案一定合法,dij就不需要做大的改动.
- 假设已拥有物品0,作为dij的起点.
- 因为n<=100,所以dij可以不用堆优化.
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int m,n,pri[110],lev[110],num[110],edge[110][110];
int d[110],ans=1e9;
bool v[110];
void init()
{
scanf("%d %d",&m,&n);
for (int i=1;i<=n;i++)
{
scanf("%d %d %d",&pri[i],&lev[i],&num[i]);
for (int j=1;j<=num[i];j++)
{
int t,v;
scanf("%d %d",&t,&v);
edge[t][i]=v;//创建一个图
}
edge[0][i]=pri[i];
}
}
int dijkstra(int mlev)
{
memset(v,0,sizeof(v));
for (int i=1;i<=n;i++)
if ((lev[i]<mlev) || (lev[i]-mlev>m)) v[i]=1;
for (int i=1;i<=n;i++) d[i]=pri[i];
for (int i=1;i<=n;i++)
{
d[n+1]=edge[109][109];//赋无穷大
int x=n+1;
for (int j=1;j<=n;j++)
if ((!v[j]) && (d[j]<d[x])) x=j;
v[x]=1;
for (int j=1;j<=n;j++)
if ((!v[j]) && (d[x]+edge[x][j]<d[j])) d[j]=d[x]+edge[x][j];
}
return d[1];
}
int main()
{
memset(edge,0x3f,sizeof(edge));
init();
for (int i=lev[1]-m;i<=lev[1];i++)//这就是基准的上下限
ans=min(ans,dijkstra(i));
printf("%d",ans);
return 0;
}
标签:POJ1062,dij,int,题解,110,聘礼,物品,include
From: https://www.cnblogs.com/xu2006/p/16636612.html