HDU - 4725 最短路

题意:

n层图,每个点放在一层,然后给了n个点,相邻的两层距离是固定的c,有额外m条边,然后求1到n的最短路径,如果没有则输出-1

 

题解:

这道题原来我想着还用1到n表示点,层用n+1到2*n表示,但是这样是不行的,因为这样建图的话就相当于同层之间的距离为0.但是事实证明不是这样的

我按照上面建图就Wa了

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<vector>
 7 using namespace std;
 8 const int INF=0x3f3f3f3f;
 9 const int maxn=3e5+5;
10 #define MAX 0xffffff
11 struct shudui1
12 {
13     int start,value;
14     bool operator < (const shudui1 q)const
15     {
16         return value>q.value;
17     }
18 } str1;
19 struct shudui2
20 {
21     int start,value;
22 } str2;
23 int v[maxn];
24 priority_queue<shudui1>r;
25 vector <shudui2>w[maxn];
26 void JK(int s)
27 {
28     memset(v,INF,sizeof(v));
29     v[s]=0;
30     str1.start=s;
31     str1.value=0;
32     r.push(str1);
33     while(!r.empty())
34     {
35         int x,y;
36         str1=r.top();
37         r.pop();
38         x=str1.start;
39         y=str1.value;
40         if(v[x]<y) continue;
41         int len=w[x].size();
42         for(int i=0; i<len; ++i)
43         {
44             str2=w[x][i];
45             if((v[x]+str2.value<v[str2.start]))
46             {
47                 v[str2.start]=v[x]+str2.value;
48                 str1.start=str2.start;
49                 str1.value=v[str2.start];
50                 r.push(str1);
51             }
52         }
53     }
54 }
55 int main()
56 {
57     int t,p=0;
58     scanf("%d",&t);
59     while(t--)
60     {
61         int n,m,k;
62         scanf("%d%d%d",&n,&m,&k);
63         for(int i=1;i<=2*n;++i)
64             w[i].clear();
65         for(int i=1;i<=n;++i)
66         {
67             int x;
68             scanf("%d",&x);
69             str2.start=n+x;
70             str2.value=0;
71             w[i].push_back(str2);
72             str2.start=i;
73             w[n+x].push_back(str2);
74         }
75         for(int i=2;i<=n;++i)
76         {
77             str2.start=n+i;
78             str2.value=k;
79             w[n+i-1].push_back(str2);
80             str2.start=n+i-1;
81             w[n+i].push_back(str2);
82         }
83         for(int i=1;i<=m;++i)
84         {
85             int x,y,z;
86             scanf("%d%d%d",&x,&y,&z);
87             str2.start=y;
88             str2.value=z;
89             w[x].push_back(str2);
90             str2.start=x;
91             w[y].push_back(str2);
92         }
93         JK(1);
94         if(v[n]!=INF)
95         printf("Case #%d: %d\n",++p,v[n]);
96         else printf("Case #%d: -1\n",++p);
97     }
98     return 0;
99 }
View Code

 

 

那就只好把每一层分成两个点,一个当作入点,一个当作出点。

第i层,入边到N+2*i-1, 出边从N+2*i 出来。(1<= i <= N)

N + 2*i    到  N + 2*(i+1)-1 加边长度为C. 表示从第i层到第j层。

N + 2*(i+1) 到 N + 2*i - 1 加边长度为C,表示第i+1层到第j层。

 

建完图直接最短路就行了

AC代码:

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<vector>
  7 using namespace std;
  8 const int INF=0x3f3f3f3f;
  9 const int maxn=3e5+5;
 10 #define MAX 0xffffff
 11 struct shudui1
 12 {
 13     int start,value;
 14     bool operator < (const shudui1 q)const
 15     {
 16         return value>q.value;
 17     }
 18 } str1;
 19 struct shudui2
 20 {
 21     int start,value;
 22 } str2;
 23 int v[maxn];
 24 priority_queue<shudui1>r;
 25 vector <shudui2>w[maxn];
 26 void JK(int s)
 27 {
 28     memset(v,INF,sizeof(v));
 29     v[s]=0;
 30     str1.start=s;
 31     str1.value=0;
 32     r.push(str1);
 33     while(!r.empty())
 34     {
 35         int x,y;
 36         str1=r.top();
 37         r.pop();
 38         x=str1.start;
 39         y=str1.value;
 40         if(v[x]<y) continue;
 41         int len=w[x].size();
 42         for(int i=0; i<len; ++i)
 43         {
 44             str2=w[x][i];
 45             if((v[x]+str2.value<v[str2.start]))
 46             {
 47                 v[str2.start]=v[x]+str2.value;
 48                 str1.start=str2.start;
 49                 str1.value=v[str2.start];
 50                 r.push(str1);
 51             }
 52         }
 53     }
 54 }
 55 int main()
 56 {
 57     int t,p=0;
 58     scanf("%d",&t);
 59     while(t--)
 60     {
 61         int n,m,k;
 62         scanf("%d%d%d",&n,&m,&k);
 63         for(int i=1;i<=3*n;++i)
 64             w[i].clear();
 65         for(int i=1;i<=n;++i)
 66         {
 67             int x;
 68             scanf("%d",&x);
 69             str2.start=n+2*x-1;
 70             str2.value=0;
 71             w[i].push_back(str2);
 72             str2.start=i;
 73             w[n+2*x].push_back(str2);
 74         }
 75         for(int i=1;i<n;++i)
 76         {
 77             str2.start=n+2*(i+1);
 78             str2.value=k;
 79             w[n+2*i-1].push_back(str2);
 80 
 81             str2.start=n+2*i;
 82             w[n+2*(i+1)-1].push_back(str2);
 83         }
 84         for(int i=1;i<=m;++i)
 85         {
 86             int x,y,z;
 87             scanf("%d%d%d",&x,&y,&z);
 88             str2.start=y;
 89             str2.value=z;
 90             w[x].push_back(str2);
 91             str2.start=x;
 92             w[y].push_back(str2);
 93         }
 94         JK(1);
 95         if(v[n]!=INF)
 96         printf("Case #%d: %d\n",++p,v[n]);
 97         else printf("Case #%d: -1\n",++p);
 98     }
 99     return 0;
100 }

 

posted @ 2020-05-06 13:11  kongbursi  阅读(98)  评论(0编辑  收藏  举报