Portal: http://poj.org/problem?id=1062
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 53123 | Accepted: 16003 |
Description
For convenience, we number all items starting from 1, the chief's promise is also regarded as an item, and the number is always 1. Each item has a corresponding price P, the owner's status level L, and a series of substitutes Ti and the "offer" Vi corresponding to the substitute. If the difference between the two's status level exceeds M, they cannot "indirect transaction". You have to use this data to figure out the minimum amount of gold an explorer needs to marry the chief's daughter.
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
The meaning of the question: This question is to find a shortest path that meets the meaning of the question. Let the starting point be S and point 1 as the destination. Now there is a way from S to 1, but the road may be very long, so some small roads can also be reached. For point 1, each place has a level, and the maximum level difference of the road you walk cannot exceed m.
Idea: Let’s talk about the construction first, start with the example: S-->1 length 10000, there are two paths, 2-->1 length 8000, 3-->1 length 5000; S-->2 length 1000, and there is 1 path, 4-->2 long 200; I believe everyone can understand how the picture is built when you see it here, and the path is equivalent to a shortcut to exchange items.
Because there is also a grade system in the question, the grade difference between any two points on the road you walk cannot exceed m, so use search to record the maximum grade and the minimum grade of each state. See the code explanation for details.
PS: 11 months ago, I just learned the shortest way. When I did this question, I felt it was too difficult to give up. Now when I go back and make up the question, I know how to write it after a while, and I have the ability to do the question. Great improvement, keep going! .
AC code:
#include<stdio.h> #include<string.h> #include<string> #include<iostream> #include<algorithm> #include<cmath> #include<map> #include<queue> #include<vector> #define delta 0.98 #define LL long long #define inf 0x3f3f3f3f #define mem(a,b) memset(a,b,sizeof(a)) #define ABS(a) a>=0?a:-a const double eps=1e-7; const int N=205; using namespace std; struct node1 { int v,nex,w; }e[10500];//代码习惯用数组模拟链表 建图 struct node { int s,l,r,num;//s表示当前所在的点,l,r表示这条路上的等级的最小最大值,num表示路长。 }; int head[N],d[N];//d数组存等级 int cnt,S,n,m;//S表示出发点0 void add(int u,int v,int w) { e[cnt].v=v; e[cnt].w=w; e[cnt].nex=head[u]; head[u]=cnt++; } void init() { mem(head,-1); S=cnt=0; } int BFS() { int ans=inf;//存最小答案 queue<node>q; node q1,q2; q1.l=q1.r=d[1];//,因为终点是1,所以初始等级可以直接设成d[1]; q1.num=q1.s=0; q.push(q1); while(!q.empty()) { q1=q.front(); q.pop(); int u=q1.s; if(u==1)//如果找到终点 { if(ans>q1.num) ans=q1.num;//跟新答案 continue; } for(int i=head[u];~i;i=e[i].nex) { q2=q1; int v=e[i].v; if(d[v]<q2.l) q2.l=d[v];//跟新最大最小等级 if(d[v]>q2.r) q2.r=d[v]; if(q2.l+m<q2.r) continue;//不符合的剪枝。 q2.num+=e[i].w; if(q2.num>=ans) continue;//路长超过答案的,剪枝 q2.s=v; q.push(q2); } } return ans; } int main() { while(~scanf("%d%d",&m,&n)) { init(); int x,a,b; for(int i=1;i<=n;i++) { scanf("%d%d%d",&a,&d[i],&x); add(S,i,a);//建大路 while(x--)//建小路 { scanf("%d%d",&a,&b); add(a,i,b); } } printf("%d\n",BFS()); } }