POJ1062 昂貴的聘禮(最短路)
阿新 • • 發佈:2017-08-02
++ namespace amp name popu 等於 ack 註意 article
說白了就是給你一張圖,每一個點有一個等級限制,在等級限制以內求一條最短路。
構圖方法:首先將原點0連向每個物品相應的編號,那麽邊權為物品的初始價格;假設對於物品j,假設有了物品i,那麽j的優惠價為w,就在i,j之間連一條權值為w的邊。最後枚舉等級的範圍(註意等級的上下差為m,當中包括了酋長的等級,而不是與酋長等級差的絕對值小於等於m QAQ),求到原點到酋長(0號點到1號點)的最短路。
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; struct T { int v; int w; int next; }edge[10010]; int head[110],cnt; void add_edge(int u,int v,int w) { edge[cnt].v = v; edge[cnt].w = w; edge[cnt].next = head[u]; head[u] = cnt++; } int m,n; int abs(int x) { return x>0?x:-x; } int dis[110]; int lv[110]; bool vis[110]; void BFS(int dn,int up)//求最短路 { memset(dis,0x3f,sizeof dis); memset(vis,0,sizeof vis); queue<int> myque; dis[0] = 0; vis[0] = 1; myque.push(0); while(!myque.empty()) { int u = myque.front(); myque.pop(); for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; int w = edge[i].w; if(!vis[v]&&lv[v] >= dn&&lv[v] <= up) { if(dis[u] + w < dis[v]) dis[v] = dis[u] + w; myque.push(v); vis[v] = 1; } else if(dis[u] + w < dis[v]&&lv[v] >= dn&&lv[v] <= up) dis[v] = dis[u] + w; } } } int main() { memset(head,-1,sizeof head); int p,x; int y,z; scanf("%d%d",&m,&n); for(int i = 1; i<= n; i++) { scanf("%d%d%d",&p,&lv[i],&x); add_edge(0,i,p); add_edge(i,0,p); for(int j = 1; j <= x; j++) { scanf("%d%d",&y,&z); add_edge(y,i,z); add_edge(i,y,z); } } int ans = 123456789; for(int i = lv[1]-m; i <= lv[1]; i++)//枚舉等級範圍 { BFS(i,i+m); if(dis[1] < ans) ans = dis[1]; } printf("%d\n",ans); }
POJ1062 昂貴的聘禮(最短路)