/**
输入:输入第一行是两个整数M,N(1 <= N <= 100),依次表示地位等级差距限制和物品的总数。
接下来按照编号从小到大依次给出了N个物品的描述。每个物品的描述开头是三个非负整数P、L、X(X < N),
依次表示该物品的价格、主人的地位等级和替代品总数。
接下来X行每行包括两个整数T和V,分别表示替代品的编号和"优惠后的价格"。
限制条件:所有参与交换的物品主人等级之间差距不超过m
输出:最少需要的金币数。
解法:构造源点0向每个物品连一条边,dist为物品本身的价格。枚举哪个物品作为等级最高的物品,
限制参与交换的物品(方法为,若某一物品等级超过了等级最高的物品,或者等级过低,把done设成true,
不参与dijkstra的运算)求出最小的金币数。
**/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <cmath>
const int inf=1<<27;
const int maxn=105;
using namespace std;
struct Edge
{
int from,to,dist;
Edge(int a,int b,int c)
{
from=a;
to=b;
dist=c;
}
};
struct node
{
int status,price;
}s[maxn];
struct HeapNode
{
int d,u;
bool operator < (const HeapNode &rhs) const
{
return d > rhs.d;
}
};
struct Dijkstra
{
int n,m;
int d[maxn];
bool done[maxn];
vector<Edge> edges;
vector<int> G[maxn];
void init(int n)
{
this->n=n;
for(int i=0;i<n;i++) G[i].clear();
edges.clear();
}
void add_edge(int from,int to,int dist)
{
edges.push_back((Edge){from,to,dist});
m=edges.size();
G[from].push_back(m-1);
}
void dijkstra(int ss)
{
priority_queue<HeapNode> q;
for(int i=0;i<n;i++) d[i]=inf;
d[ss]=0;
q.push((HeapNode){0,ss});
while(!q.empty())
{
HeapNode x=q.top();
int u=x.u;
q.pop();
if(done[u])continue;
done[u]=true;
for(int i=0;i<G[u].size();i++)
{
Edge &e=edges[G[u][i]];
if(!done[e.to] && d[e.to]>d[u]+e.dist)
{
d[e.to]=d[u]+e.dist;
q.push((HeapNode){d[e.to],e.to});
}
}
}
}
};
int main()
{
int m,n,i,x,j,num,cut,maxlv;
Dijkstra solver;
scanf("%d%d",&m,&n);
solver.init(n+1);
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&s[i].price,&s[i].status,&x);
for(j=0;j<x;j++)
{
scanf("%d%d",&num,&cut);
solver.add_edge(num,i,cut);
}
solver.add_edge(0,i,s[i].price);
}
int ans=s[1].price;
for(i=1;i<=n;i++)
{
maxlv=s[i].status;
for(j=1;j<=n;j++)
{
if(s[j].status>maxlv || maxlv-s[j].status>m) solver.done[j]=true;
else solver.done[j]=false;
}
solver.done[0]=false;
solver.dijkstra(0);
ans=min(ans,solver.d[1]);
}
printf("%d\n",ans);
return 0;
}
poj 1062(Kuangbin最短路专题M题)
最新推荐文章于 2022-04-21 19:42:42 发布