POJ1062

题目链接:http://poj.org/problem?id=1062

解题思路:

  枚举区间+Dijkstra

  一开始理解错了题意,WA了好久。后来参考题解才AC了。

  把每一样物品看成一个点,由物品A换到物品B看成从A指向B的边,这样一来就把问题转换成最短路问题了,具体实现看代码吧。。。关键是枚举区间这一个细节。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <cmath>
 5 #include <algorithm>
 6 using namespace std;
 7 const int inf=0xfffffff;
 8 const int maxn=100+10;
 9 int thing[maxn],ranks[maxn],vis[maxn],d[maxn];
10 vector<pair<int,int> > vc[maxn];  //a,b           ,ma[maxn],mi[maxn]
11 int road[maxn][maxn];
12 int M,N,t;
13 int dijkstra(int l,int r){
14     for(int i=1;i<=N;i++) {
15         vis[i]=0;
16         d[i]=inf;
17     }
18     d[1]=thing[1];
19     while(1){
20         int v=-1;
21         for(int u=1;u<=N;u++){
22             if(!vis[u]&&(v==-1||d[u]<d[v])) v=u;
23         }
24         if(v==-1)   break;
25         vis[v]=1;
26         for(int u=1;u<=N;u++){
27             if(ranks[u]<=r&&ranks[u]>=l&&d[u]>d[v]+road[v][u]-thing[v]){
28                 d[u]=d[v]+road[v][u]-thing[v];
29             }
30         }
31     }
32     int ans=inf;
33     for(int i=1;i<=N;i++){
34         if(ans>d[i])    ans=d[i];
35     }
36     return ans;
37 }
38 int main(){
39     scanf("%d%d",&M,&N);
40     for(int i=1;i<=N;i++){
41         scanf("%d%d%d",&thing[i],&ranks[i],&t);
42         while(t--){
43             int a,b;
44             scanf("%d%d",&a,&b);
45             vc[i].push_back(make_pair(a,b));
46         }
47     }
48     for(int i=1;i<=N;i++){
49         for(int j=i;j<=N;j++){
50             if(i==j)
51                 road[i][j]=thing[i];
52             else
53                 road[i][j]=road[j][i]=inf;
54         }
55     }
56     for(int i=1;i<=N;i++){
57         for(int j=0;j<vc[i].size();j++){
58             int a=vc[i][j].first,b=vc[i][j].second;
59             if(abs(ranks[a]-ranks[i])>M)    continue;
60             road[i][a]=b+thing[a];
61         }
62     }
63     int ans=inf;
64     for(int i=ranks[1]-M;i<=ranks[1];i++){
65         int temp=dijkstra(i,i+M);
66         if(temp<ans)    ans=temp;
67     }
68 
69 
70     printf("%d
",ans);
71     return 0;
72 }
View Code
“这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
原文地址:https://www.cnblogs.com/Blogggggg/p/7246460.html