POJ1062不错的题——spfa倒向建图——枚举等级限制
虽然是中文题目但是还是有一定几率都不准题目意思的:1.所有可能降价的措施不是降价多少钱而是降至多少钱2.等级范围:是你所走的那一条路中所有人中最好最低等级差不允许超过limit限制
思路确实没有想好:导致我也苦想冥思了很久,没有想到逆向构思其实这个题意你如果理解了,算起来也是逆向的~~肯定得花钱入手一个原价的然后层层入手优惠的直至买到1号物品,所以加了一个开始节点0,构建路也是逆向,例如买2可以优惠1,我就可以建2 -》1
第二点:对于等级的处理,这个真的是用了许多的方法,都没能全面的起作用,看了题解之后,明白了:枚举等级空间,因为我的等级空间是会首受限制的但是一开始就是m对于5级的1限制我要枚举的是假想的最大等级—也就是3,5|4,6,|5,7 也就是我要交流的就是和最低等级为3最高等级为5或者最低等级为4 最高等级为6 ……的
接下来,你会发现这个题的代码,和这个的思路一样的好看
#include <string.h> #include <iostream> #include <cstdio> #include <vector> #include <queue> #define inf 0x3f3f3f3f using namespace std; const int maxn = 110; int mp[maxn][maxn]; int dis[maxn],vis[maxn]; struct node { int price,state; }data[maxn]; int lim,n; queue<int> q; int spfa(int l,int r) { while(q.size())q.pop(); memset(vis,0,sizeof(vis)); for(int i = 1;i <= n;i++) { dis[i] = inf; } dis[0] = 0;vis[0] = 1; q.push(0); while(q.size()) { int now = q.front();q.pop(); vis[now] = 0; for(int i = 1;i <= n;i++) { if(data[i].state < l || data[i].state > r)continue; if(dis[i] > dis[now] + mp[now][i]) { dis[i] = dis[now] + mp[now][i]; if(!vis[i]) { vis[i] = 1; q.push(i); } } } } return dis[1]; } int main() { while(~scanf("%d%d",&lim,&n)) { for(int i = 0;i <= n;i++) { for(int j = 0;j <= n;j++) { i == j ? mp[i][j] = 0 : mp[i][j] = mp[j][i] = inf; } } int x; for(int i = 1;i <= n;i++) { scanf("%d%d%d",&data[i].price,&data[i].state,&x); mp[0][i] = data[i].price;//倒图思想,我一开始肯定原价得进手一个图 while(x--) { int a; scanf("%d",&a); scanf("%d",&mp[a][i]); } } int ans = inf; for(int i = data[1].state - lim;i <= data[1].state;i++) { ans = min(ans,spfa(i,i+lim)); } printf("%d\n",ans); } return 0; }