标签:
http://poj.org/problem?id=1062
Description
Input
Output
Sample Input
1 4 10000 3 2 2 8000 3 5000 1000 2 1 4 200 3000 2 1 4 200 50 2 0
Sample Output
5250
/** poj 1062 带有限制的最短路(需要稍该模板) 题目大意:每个人都有一个物品,对应一定的钱数,想要得到此物品可以直接出钱, 也可以通过用其他人的物品并添加一些钱来交换,问要得到酋长的物品最少需要多少钱? 另外,每个人都有一个等级,要求和你交易的人中不能有任何两人的等级相差m以上。 解题思路:(转)我们可以把本题理解为,我们要买一号物品,而一个物品的一部分价值可以转化为别的物品, 我们通过购买别的物品和加钱来购买获得一号物品。所以我们可以把需要加的钱数作为该物品到 别的物品的一条边,走过这条边,我们要花一些钱,然后我们只需要购买现在所在结点的物品即可。 这样就把问题转化为最短路问题,用dijkstra就可以了。关于等级限制的问题。我们可以每次枚举 一个宽为m的等级区间,忽略不在区间内的点,进行spfa。 */ #include <iostream> #include <cstdio> #include <cmath> #include <queue> #include <string.h> #include <algorithm> using namespace std; const int INF=0x3f3f3f3f; const int maxm=5111; const int maxn=111; struct EdgeNode { int to; int w; int next; } edges[maxm]; int n,m; int head[maxn],edge; int a[maxn],ra[maxn]; bool vis[maxn]; int dis[maxn],dist[maxn],level[maxn]; void addedge(int u,int v,int c) { edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++; } void init() { memset(head,-1,sizeof(head)); edge=0; } void spfa(int floor) { int s=0; int u; for (int i=0; i<=n; i++) dis[i]=INF; memset(vis,0,sizeof(vis)); queue <int> que; que.push(s); vis[s]=true; dis[s]=0; while (!que.empty()) { u=que.front(); que.pop(); vis[u]=false; for (int i=head[u]; i!=-1; i=edges[i].next) { int v=edges[i].to; int w=edges[i].w; if ((dis[v]>dis[u]+w )&&ra[v]>=floor && ra[v]<=floor+m)///满足等级在枚举的等级区间内 { dis[v]=dis[u]+w; if (!vis[v]) { vis[v]=true; que.push(v); } } } } for(int i=0; i<n; i++) { if(dist[i]>dis[i]) dist[i]=dis[i]; } } int main() { while(~scanf("%d%d",&m,&n)) { for(int i=0; i<=n; i++) dist[i]=INF; init(); int levelnum=0; for(int i=0; i<n; i++) { int num; scanf("%d%d%d",&a[i],&ra[i],&num); level[levelnum++]=ra[i]; for(int j=0; j<num; j++) { int w,x; scanf("%d%d",&x,&w); addedge(i,x-1,w); } } sort(level,level+levelnum); levelnum=unique(level,level+levelnum)-level; for(int i=0; i<levelnum; i++) { if(ra[0]>=level[i]&&ra[0]<=level[i]+m) spfa(level[i]); } int ans=INF; for(int i=0; i<n; i++) { ans=min(ans,dist[i]+a[i]); } printf("%d\n",ans); } return 0; } /** 1 4 100 3 2 2 8000 3 5000 1000 2 1 4 200 3000 2 1 4 200 50 2 0 1 4 10000 3 2 2 8000 3 5000 1000 2 1 4 200 3000 12 1 4 200 50 2 0 1 4 10000 3 2 2 8000 3 5000 1000 2 1 4 200 3000 2 1 4 200 50 12 0 1 4 100 3 2 2 8000 3 5000 1000 2 1 4 200 3000 2 1 4 200 50 2 0 1 4 10000 3 2 2 8000 3 5000 1000 2 1 4 200 3000 12 1 4 200 50 2 0 1 4 10000 3 2 2 8000 3 50000 1000 2 1 4 200 3000 2 1 4 200 50 12 0 */
标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/42560323