转化为:0节点出发,到1节点的最小值,每一个节点的本身价值就是0节点直接到这个节点的权,因为这个东西只需要钱,不需要再去弄别的,兑换就是他的子节点会通过一定的权值到这个节点.一开始没看懂题意,以为只是交易的两个人有等级限制,原来是都有等级限制.这个等级限制可以通过枚举每一范围来确定留下那些边,下面是代码
#include<stdio.h> #include<string.h> #include<queue> #include<math.h> #include<algorithm> using namespace std; int n,m,cnt=0; struct aa { int x,y,w,next; } save[100086]; int per[100086]; int leve[100086]; int dist[100086]; int vis[100086]; int fib[100086]; void add(int a,int b,int w) { save[cnt].x=a,save[cnt].y=b,save[cnt].w=w; save[cnt].next=per[a]; per[a]=cnt++; } int spfa(int key) { dist[0]=0; queue<int>ycq; ycq.push(0); while(!ycq.empty()) { int t=ycq.front(); ycq.pop(); vis[t]=0; for(int i=per[t]; i!=-1; i=save[i].next) { if(!fib[i]) continue; int x=save[i].x; int y=save[i].y; int w=save[i].w; if(dist[y]>dist[x]+w) { dist[y]=dist[x]+w; if(!vis[y]) { vis[y]=1; ycq.push(y); } } } } return dist[key]; } int main() { while(scanf("%d%d",&m,&n)!=EOF) { cnt=0; memset(per,-1,sizeof(per)); for(int i=1; i<=n; i++)//建边 { int a,b,c; scanf("%d%d%d",&a,&b,&c); leve[i]=b; add(0,i,a); while(c--) { int temp1,temp2; scanf("%d%d",&temp1,&temp2); add(temp1,i,temp2); } } int minn=0x3f3f3f3f; for(int i=0; i<=m; i++)//筛选 { memset(fib,0,sizeof(fib)); memset(dist,0x3f3f3f3f,sizeof(dist)); memset(vis,0,sizeof(vis)); for(int j=0; j<cnt; j++) { int u=save[j].x; int v=save[j].y; if(u==0) { if(leve[v]>=(leve[1]-m+i)&&(leve[v]<=leve[1]+i)) fib[j]=1; continue; } if(leve[u]>=(leve[1]-m+i)&&(leve[u]<=leve[1]+i)&&leve[v]>=(leve[1]-m+i)&&(leve[v]<=leve[1]+i)) { fib[j]=1; } } minn=min(spfa(1),minn); } printf("%d\n",minn); } }