【最短路】分层图最短路 分层图最短路

参考博客:

分层图最短路

分层图最短路--最通俗易懂的讲解


小说

题目描述

由于小X是一位奆老,奆老总是忙得一刻也停不下来。他刚刚准备完食物,小X童年的挚友小S和小Z来找他帮忙了……
小S和小Z十分喜欢看网络写手“25”的小说,但由于需要付费才能阅读,而小S和小Z的零花钱有非常少,他们只能找小X靠黑科技侵入给网站,把小说给他们。
然而小X又非常的爱慕虚荣,他要小S和小Z到自己家里来取小说。
小S、小Z和小X都居住在扬中市,扬中市共有n个小区,m条主干道(假设每条主干道都是双行线)。小S家住在1号小区,小X家住在n号小区。小S每经过一条主干道需要耗费z点体力,但由于小S的人脉非常广,每当他到达一个小区,他都会和好友攀谈直到体力回满。
由于小Z也希望能看到小说,所以他答应帮助小S k次,这k次小S经过主干道不需要耗费体力。
由于小S生性懒惰,他希望耗费最少的体力到达小X家,请问他最少耗费多少体力?
注意:如果小S到小X家可以一路上都由小Z背着,那么体力上限为0;
如果小S到不了小X家,小S会很伤心,体力上限为-1;

输入

第1行三个整数n,m,k,意思如题目描述。
第2到第n+1行是x,y,z指走连接x号小区和y号小区的主干道要耗费z点体力

输出

一行一个整数,表示小S最少耗费的体力。

样例输入

5 7 1
1 2 5
3 1 4
2 4 8
3 2 3
5 2 9
3 4 7
4 5 6

样例输出

4

提示

小S的行走路线:1->3->2->5,其中2->5这条主干道由小Z帮助小S通过。

对于30%的数据:n<=20;m<=100;
对于60%的数据:n<=100;m<=1000;
对于100%的数据:n<=1000;m<=10000;z<=1000000;

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1005 ;
 4 const int M = 10005;
 5 
 6 /*          */
 7 
 8 typedef struct Edge{
 9     int to , next , w ;
10 }Edge;
11 
12 Edge e[M<<1] ;
13 
14 int head[N],idx ;
15 
16 void Add_edge( int u , int v ,int w ){
17     e[idx] = Edge{ v , head[u] , w };
18     head[u] = idx ++ ;
19 }
20 
21 void Init(){
22     memset( head , -1 , sizeof head );
23     idx = 0;
24 }
25 
26 /*              */
27 typedef struct Node{
28     int u , w ;
29     Node ( int _u = 0 , int _w = 0 ){
30         u = _u , w = _w ;
31     }
32     bool operator < ( const Node &rhs ) const {
33         return w > rhs.w ;
34     }
35 }Node;
36 
37 int vis[N],dis[N];
38 int n,m,k;
39 bool Dijstra( int Len ){
40 
41     memset( dis , 0x3f , sizeof dis );
42     memset( vis , 0 ,sizeof vis );
43 
44     dis[1] = 0 ;
45 
46     priority_queue < Node > Q ;
47     Q.push( Node(1,0) );
48 
49     int cnt = 0 ;
50     while( !Q.empty() ){
51         Node cur = Q.top();
52         Q.pop();
53         int u = cur.u , w = cur.w ;
54 
55         if( vis[u] ) continue ;
56         vis[u] = 1 ;
57 
58         for( int i = head[u] ; ~i ; i = e[i].next ){
59             int To = e[i].to  ;
60             int w = e[i].w > Len ? 1 : 0 ;
61             if( dis[To] > dis[u] + w ){
62                 dis[To] = dis[u] + w ;
63                 Q.push( Node(To,dis[To]) );
64             }
65         }
66     }
67     return dis[n] <= k ;
68 }
69 int main()
70 {
71     Init();
72     ios_base :: sync_with_stdio(false);
73     cin.tie(NULL) , cout.tie(NULL) ;
74     cin >> n >> m >> k ;
75 
76     for( int i = 0,u,v,w; i < m ; i++ ){
77         cin >> u >> v >> w ;
78         Add_edge( u,v,w );
79         Add_edge( v,u,w );
80     }
81     //cout << "### "<< endl;
82     int L = 0 , R = 0x3f3f3f3f ;
83     while( L < R ){
84         int Mid = L + R >> 1 ;
85         if( Dijstra( Mid ) ){
86             R = Mid ;
87         }else{
88             L = Mid + 1 ;
89         }
90     }
91     if( dis[n] > 1e6+10 ){
92         printf("-1\n");
93     }else{
94         printf("%d\n",R);
95     }
96     return 0;
97 }
二分做法
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1e6+10 ;
 4 const int M = 1e6+10;
 5 
 6 /*          */
 7 
 8 typedef struct Edge{
 9     int to , next , w ;
10 }Edge;
11 
12 Edge e[M<<1] ;
13 
14 int head[N],idx ;
15 
16 void Add_edge( int u , int v ,int w ){
17     e[idx] = Edge{ v , head[u] , w };
18     head[u] = idx ++ ;
19 }
20 
21 void Init(){
22     memset( head , -1 , sizeof head );
23     idx = 0;
24 }
25 
26 /*              */
27 typedef struct Node{
28     int u , w ;
29     Node ( int _u = 0 , int _w = 0 ){
30         u = _u , w = _w ;
31     }
32     bool operator < ( const Node &rhs ) const {
33         return w > rhs.w ;
34     }
35 }Node;
36 
37 int vis[N],dis[N];
38 int n,m,k;
39 void Dijstra(){
40 
41     memset( dis , 0x3f , sizeof dis );
42     memset( vis , 0 ,sizeof vis );
43 
44     dis[1] = 0 ;
45 
46     priority_queue < Node > Q ;
47     Q.push( Node(1,0) );
48 
49     int cnt = 0 ;
50     while( !Q.empty() ){
51         Node cur = Q.top();
52         Q.pop();
53         int u = cur.u , w = cur.w ;
54         if( vis[u] ) continue ;
55         vis[u] = 1 ;
56         for( int i = head[u] ; ~i ; i = e[i].next ){
57             int To = e[i].to  ;
58             int w = max( e[i].w , dis[u] );
59             if( dis[To] > w ){
60                 dis[To] = w ;
61                 Q.push( Node( To,dis[To] ) );
62             }
63         }
64     }
65 }
66 int main()
67 {
68     Init();
69     ios_base :: sync_with_stdio(false);
70     cin.tie(NULL) , cout.tie(NULL) ;
71     cin >> n >> m >> k ;
72 
73     for( int i = 0,u,v,w; i < m ; i++ ){
74         cin >> u >> v >> w ;
75         for( int j = 0 ; j <= k ; j++ ){
76             Add_edge( u + (j*n) , v + (j*n) , w );
77             Add_edge( v + (j*n) , u + (j*n) , w );
78             if( j != k ){
79                 Add_edge( u + (j*n) , v + (j+1)*n , 0 );
80                 Add_edge( v + (j*n) , u + (j+1)*n , 0 );
81             }
82         }
83     }
84 
85     Dijstra();
86     int ans = 0x3f3f3f3f ;
87     ans = min( ans , dis[n + n*k] ) ;
88 
89     printf("%d\n",ans==0x3f3f3f3f ? -1 : ans );
90     return 0;
91 }
分层图第一种写法
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N = 1e3+10 ;
  4 const int M = 1e5+10 ;
  5 const int K = 1e3+10 ;
  6 
  7 /*          */
  8 
  9 typedef struct Edge{
 10     int to , next , w ;
 11 }Edge;
 12 
 13 Edge e[M<<1] ;
 14 
 15 int head[N],idx ;
 16 
 17 void Add_edge( int u , int v ,int w ){
 18     e[idx] = Edge{ v , head[u] , w };
 19     head[u] = idx ++ ;
 20 }
 21 
 22 void Init(){
 23     memset( head , -1 , sizeof head );
 24     idx = 0;
 25 }
 26 
 27 /*              */
 28 typedef struct Node{
 29     int u , w ;
 30     Node ( int _u = 0 , int _w = 0 ){
 31         u = _u , w = _w ;
 32     }
 33     bool operator < ( const Node &rhs ) const {
 34         return w > rhs.w ;
 35     }
 36 }Node;
 37 
 38 
 39 int n,m,k;
 40 int vis[N][K],dis[N][K];
 41 void Dijstra(){
 42 
 43     memset( dis , 0x3f , sizeof dis );
 44     memset( vis , 0 ,sizeof vis );
 45 
 46     dis[0][0] = 0 ;
 47 
 48     priority_queue < Node > Q ;
 49     Q.push( Node(0,0) );
 50 
 51     while( !Q.empty() ){
 52         Node cur = Q.top();
 53         Q.pop();
 54         int c = cur.u / n ;
 55         int u = cur.u % n ;
 56         if( vis[u][c] ) continue ;
 57         vis[u][c] = 1 ;
 58         for( int i = head[u] ; ~i ; i = e[i].next ){
 59             int To = e[i].to  ;
 60             int w = max( e[i].w , dis[u][c] );
 61             if( dis[To][c] > w && !vis[To][c] ){
 62                 dis[To][c] = w ;
 63                 Q.push( Node( To + c * n , dis[To][c] ) );
 64             }
 65         }
 66         if( c < k ){
 67             for( int i = head[u] ; ~i ; i = e[i].next ){
 68                 int To = e[i].to  ;
 69                 int w =  dis[u][c] ;
 70                 if( dis[To][c+1] > w && !vis[To][c+1] ){
 71                     dis[To][c+1] = w ;
 72                     Q.push( Node( To + (c+1) * n , dis[To][c+1] ) );
 73                 }
 74             }
 75         }
 76 
 77     }
 78 }
 79 int main()
 80 {
 81     Init();
 82     ios_base :: sync_with_stdio(false);
 83     cin.tie(NULL) , cout.tie(NULL) ;
 84     cin >> n >> m >> k ;
 85 
 86     for( int i = 0,u,v,w; i < m ; i++ ){
 87         cin >> u >> v >> w ;
 88         u -- , v -- ;
 89         Add_edge( u , v , w );
 90         Add_edge( v , u , w );
 91     }
 92 
 93     Dijstra();
 94     int ans = 0x3f3f3f3f ;
 95     for( int i = 0 ; i <= k ; i++ ){
 96         ans = min( ans , dis[n-1][i] );
 97     }
 98 
 99     printf("%d\n",ans==0x3f3f3f3f ? -1 : ans );
100     return 0;
101 }
分层图第二种写法

P4568 [JLOI2011]飞行路线

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N = 2e5+10;
 4 const int M = 2e6+10;
 5 
 6 typedef struct Edge{
 7     int to , next , w ;
 8 }Edge;
 9 
10 Edge e[M<<1] ;
11 int head[N] , idx ;
12 
13 void add_edge(int u , int v , int w ){
14     e[idx] = Edge{ v , head[u] , w };
15     head[u] = idx ++ ;
16 }
17 void Init(){
18     memset( head , -1 , sizeof head );
19     idx = 0 ;
20 }
21 int n , m , k ;
22 int S , T ;
23 int dis[N] , vis[N] ;
24 
25 typedef struct Node{
26     int u , w ;
27     Node( int _u = 0 , int _w = 0 ){
28         u = _u , w = _w ;
29     }
30     bool operator < ( const Node & rhs )const{
31         return w > rhs.w ;
32     }
33 }Node;
34 
35 void Dijstra(int S){
36 
37     memset( vis , 0 , sizeof vis );
38     memset( dis , 0x3f , sizeof dis );
39     dis[S] = 0 ;
40 
41     priority_queue < Node > Q ;
42     Q.push( Node(S,0) );
43 
44     while( !Q.empty() ){
45         Node cur = Q.top();
46         Q.pop() ;
47         int u = cur.u ;
48         if( vis[u] ) continue ;
49         vis[u] = 1 ;
50 
51         for( int i = head[u] ; ~i ; i = e[i].next ){
52             int To = e[i].to ;
53             int w = e[i].w ;
54             if( !vis[To] && dis[u] + w < dis[To] ){
55                 dis[To] = dis[u] + w ;
56                 Q.push( Node( To , dis[To] ) );
57             }
58         }
59     }
60 }
61 
62 int main()
63 {
64     Init();
65     ios_base :: sync_with_stdio(false);
66     cin.tie(NULL) , cout.tie(NULL) ;
67 
68 
69     cin >> n >> m >> k ;
70     cin >> S >> T ;
71 
72     for( int i = 0,u,v,w; i < m ; i++ ){
73         cin >> u >> v >> w ;
74         for( int j = 0 ; j <= k ; j ++ ){
75             add_edge( u + j*n , v + j*n , w );
76             add_edge( v + j*n , u + j*n , w );
77             if( j != k ){
78                 add_edge( u + j*n , v + (j+1)*n , 0 ) ;
79                 add_edge( v + j*n , u + (j+1)*n , 0 ) ;
80             }
81         }
82     }
83     Dijstra(S);
84     int ans = 0x3f3f3f3f ;
85     for( int i = 0 ; i <= k ; i++ ){
86         ans = min( ans , dis[ T+i*n ]);
87     }
88     cout << ans << endl ;
89     return 0;
90 }
View Code



P3831 [SHOI2012]回家的路

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N = 5e5 + 10;
  4 const int M = 5e6 + 10;
  5 
  6 typedef struct Edge{
  7     int to , next , w ;
  8 }Edge;
  9 Edge e[M<<1] ;
 10 
 11 int head[N] , idx ;
 12 void Add_edge( int u , int v , int w ){
 13     e[idx] = Edge{ v , head[u] , w };
 14     head[u] = idx ++ ;
 15 }
 16 
 17 void Init(){
 18     memset( head , -1 , sizeof head );
 19     idx = 0 ;
 20 }
 21 typedef struct P{
 22     int x , y , No ;
 23 }P;
 24 P a[N] ;
 25 bool cmp1(P u,P v){
 26     if( u.x == v.x ) return u.y < v.y ;
 27     return u.x < v.x ;
 28 }
 29 bool cmp2(P u,P v ){
 30     if( u.y == v.y ) return u.x < v.x ;
 31     return u.y < v.y ;
 32 }
 33 
 34 int n,m,S,T,k;
 35 int dis[N],vis[N];
 36 
 37 typedef struct Node{
 38     int u,w;
 39     Node ( int _u = 0 , int _w = 0 ):u(_u),w(_w){}
 40     bool operator < (const Node &rhs )const {
 41         return w > rhs.w ;
 42     }
 43 }Node;
 44 void Dijstra(int S){
 45     memset( dis , 0x3f , sizeof dis );
 46     memset( vis , 0 , sizeof vis );
 47 
 48     dis[S] = 0 ;
 49     priority_queue < Node > Q;
 50     Q.push( Node(S,0) );
 51 
 52 
 53     while(!Q.empty() ){
 54 
 55         Node cur = Q.top();
 56         Q.pop();
 57         int u = cur.u;
 58         if( vis[u] ) continue ;
 59         vis[u] = 1 ;
 60 
 61         //printf("#### %d ### \n",u);
 62 
 63         for( int i = head[u] ; ~i ; i = e[i].next ){
 64             int To = e[i].to ;
 65             int w = e[i].w ;
 66             if( dis[To] > dis[u] + w ){
 67                 dis[To] = dis[u] + w ;
 68                 Q.push( Node(To,dis[To] ) );
 69             }
 70         }
 71     }
 72 }
 73 
 74 
 75 int main()
 76 {
 77     ios_base :: sync_with_stdio(false);
 78     cin.tie(NULL) , cout.tie(NULL) ;
 79 
 80     cin >> n >> m ;
 81 
 82     Init() ;
 83     S = m + 1 , T = m + 2 ;
 84     n = m + 2 ;
 85 
 86     for( int i = 1; i <= n ; i++ ){
 87         cin >> a[i].x >> a[i].y ;
 88         a[i].No = i ;
 89     }
 90 
 91     sort( a + 1 , a + 1 + n , cmp1 );
 92     for( int i = 1 ; i < n ; i ++ ){
 93         if( a[i].x == a[i+1].x ){
 94             Add_edge( a[i].No , a[i+1].No , 2 * (a[i+1].y-a[i].y) );
 95             Add_edge( a[i+1].No , a[i].No , 2 * (a[i+1].y-a[i].y) );
 96         }
 97     }
 98 
 99     sort( a + 1 , a + 1 + n , cmp2 );
100     for( int i = 1 ; i < n ; i ++ ){
101         if( a[i].y == a[i+1].y ){
102             Add_edge( a[i].No+n , a[i+1].No+n , 2 * (a[i+1].x-a[i].x));
103             Add_edge( a[i+1].No+n , a[i].No+n , 2 * (a[i+1].x-a[i].x) );
104         }
105     }
106 
107     for( int i = 1 ; i <= m ; i++ ){
108         Add_edge( i , i+n , 1 );
109         Add_edge( i+n , i , 1 );
110     }
111     Add_edge( S + n , S , 0 );
112     Add_edge( S , S + n , 0 );
113     Add_edge( T , T + n , 0 );
114     Add_edge( T + n , T , 0 );
115 
116     Dijstra(S);
117     printf("%d\n",dis[T] == 0x3f3f3f3f ? -1 : dis[T] );
118     return 0;
119 }
View Code

爱情之路

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N = 5e5 + 10;
 4 const int M = 5e6 + 10;
 5 
 6 typedef struct Edge{
 7     int to , next , w , ch ;
 8 }Edge;
 9 Edge e[M<<1] ;
10 
11 int head[N] , idx ;
12 void Add_edge( int u , int v , int w , int ch ){
13     e[idx] = Edge{ v , head[u] , w , ch };
14     head[u] = idx ++ ;
15 }
16 
17 void Init(){
18     memset( head , -1 , sizeof head );
19     idx = 0 ;
20 }
21 typedef struct P{
22     int x , y , No ;
23 }P;
24 P a[N] ;
25 
26 int n,m,S,T,k;
27 int dis[N][5],vis[N][5];
28 int cnt[N][5];
29 
30 typedef struct Node{
31     int u , w , id ;
32     Node ( int _u = 0 , int _w = 0 ,int Id = 0 ):u(_u),w(_w),id(Id){}
33     bool operator < (const Node &rhs )const {
34         return w > rhs.w ;
35     }
36 }Node;
37 void Dijstra(int S){
38     memset( dis , 0x3f , sizeof dis );
39     memset( vis , 0 , sizeof vis );
40 
41     dis[S][0] = cnt[S][0] = 0 ;
42 
43     priority_queue < Node > Q;
44     Q.push( Node(S,0,0) );
45 
46     while( !Q.empty() ){
47         Node cur = Q.top();
48         Q.pop();
49 
50         int u = cur.u , id = cur.id ;
51         if( vis[u][id] ) continue ;
52         vis[u][id] = 1 ;
53 
54         //printf("##### %d #### \n",u);
55         for( int i = head[u] ; ~i ; i = e[i].next ){
56             int To = e[i].to ;
57             int ch = e[i].ch ;
58             int w = e[i].w ;
59 
60             if( ch == id % 4 + 1 && dis[To][ch] > dis[u][id] + w ){
61                 dis[To][ch] = dis[u][id] + w ;
62                 cnt[To][ch] = dis[u][id] + 1 ;
63                 Q.push( Node( To , dis[To][ch] , ch ) ) ;
64             }
65         }
66     }
67 }
68 
69 
70 int main()
71 {
72     ios_base :: sync_with_stdio(false);
73     cin.tie(NULL) , cout.tie(NULL) ;
74 
75     cin >> n >> m ;
76 
77     Init() ;
78     char ch[10];
79     int Type ;
80     for( int i = 1 , u , v , w ; i <= m ; i++ ){
81         cin >> u >> v >> w >> ch ;
82         switch( ch[0] ){
83             case 'L' : Type = 1 ; break ;
84             case 'O' : Type = 2 ; break ;
85             case 'V' : Type = 3 ; break ;
86             case 'E' : Type = 4 ; break ;
87         }
88         Add_edge( u , v , w , Type );
89         Add_edge( v , u , w , Type );
90     }
91     Dijstra( 1 );
92     if( dis[n][4] != 0x3f3f3f3f ){
93         printf("%d %d\n",dis[n][4] , cnt[n][4] >> 2 );
94     }else{
95         puts("HOLY SHIT!");
96     }
97     return 0;
98 }
View Code

POJ-1724 Road

 1 #include<iostream>
 2 #include<cstring>
 3 #include<queue>
 4 #include<algorithm>
 5 using namespace std;
 6 const int inf = 0x3f3f3f3f ;
 7 const int N = 308 ;
 8 const int M = 1e4+10;
 9 int n , m , k , idx ;
10 int head[N] , ans ;
11 int vis[N][M];
12 int dis[N][M];
13 
14 typedef struct Edge{
15     int to , next , w, val ;
16 }Edge ;
17 Edge e[M<<1];
18 
19 typedef struct Node{
20     int u,w,val;
21     Node( int _u = 0 , int _w = 0 , int v = 0 )
22     :u(_u),w(_w),val(v){}
23 
24     bool operator < ( const Node &rhs ) const{
25         return w > rhs.w ;
26     }
27 }Node;
28 
29 void Add_edge( int u , int v , int w , int val ){
30     e[idx] = Edge { v , head[u] , w , val };
31     head[u] = idx ++ ;
32 }
33 void Init(){
34     memset( head , -1 , sizeof head );
35     idx = 0 ;
36 }
37 void Dijstra(){
38     memset( dis , 0x3f , sizeof dis );
39     memset( vis , 0 , sizeof vis );
40     dis[1][k] = 0 ;
41     priority_queue < Node > Q ;
42     Q.push( Node(1,0,k) );
43     while( !Q.empty() ){
44         Node cur = Q.top();
45         Q.pop();
46         int u = cur.u ;
47         int k = cur.val ;
48         if( vis[u][k] ) continue ;
49         vis[u][k] = 1 ;
50         for( int i = head[u] ; ~i ; i = e[i].next ){
51             int to = e[i].to ;
52             int val = e[i].val ;
53             int w = e[i].w ;
54 
55             if( k >= val ){
56                 if( dis[to][k-val] > dis[u][k] + w ){
57                     dis[to][k-val] = dis[u][k] + w ;
58                     Q.push( Node( to , dis[to][k-val] , k-val ) );
59                 }
60             }
61         }
62     }
63 }
64 
65 int main()
66 {
67     Init();
68     ios_base :: sync_with_stdio(false);
69     cin.tie(NULL) , cout.tie(NULL) ;
70     cin >> k >> n >> m ;
71     for( int i = 0,u,v,w,val ; i < m ; i++ ){
72         cin >> u >> v >> w >> val ;
73         Add_edge( u , v , w , val );
74         //Add_edge( v , u , w , val );
75     }
76     Dijstra();
77     ans = inf ;
78     for( int i = 0 ; i <= k ; i++ )
79         ans = min( ans , dis[n][i] );
80     if( ans == inf )
81         cout << -1 << endl ;
82     else
83         cout << ans << endl ;
84     return 0;
85 }
View Code

P4822 [BJWC2012]冻结

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1e6+10;
 4 const int M = 1e6+10;
 5 
 6 typedef struct Edge{
 7     int to , next , w ;
 8 }Edge ;
 9 Edge e[M<<1] ;
10 
11 typedef struct Node{
12     int u , w ;
13     Node( int _u = 0 , int _w = 0 ):u(_u),w(_w){}
14     bool operator < ( const Node &rhs ) const {
15         return w > rhs.w ;
16     }
17 }Node;
18 
19 int head[N] , idx ;
20 void Add_Edge( int u , int v , int w ){
21     e[idx] = Edge{ v , head[u] , w };
22     head[u] = idx ++ ;
23 }
24 
25 int dis[N] , vis[N] ;
26 int n , m , k ;
27 
28 void Init(){
29     memset( head , -1 , sizeof head );
30     idx = 0 ;
31 }
32 
33 void Dijstra(){
34     memset( dis , 0x3f , sizeof dis );
35     memset( vis , 0 , sizeof vis );
36 
37     dis[1] = 0 ;
38     priority_queue < Node > Q;
39     Q.push( Node(1,0) ) ;
40     while( !Q.empty() ){
41         Node cur = Q.top() ;
42         Q.pop() ;
43         int u = cur.u ;
44         if( vis[u] ) continue ;
45         vis[u] = 1 ;
46 
47         for( int i = head[u] ; ~i ; i = e[i].next ){
48             int To = e[i].to ;
49             int w = e[i].w ;
50             if( dis[To] > dis[u] + w ){
51                 dis[To] = dis[u] + w ;
52                 Q.push( Node( To, dis[To] ) );
53             }
54         }
55     }
56 }
57 
58 int main()
59 {
60     ios_base :: sync_with_stdio(false);
61     cin.tie(NULL) , cout.tie(NULL) ;
62     Init() ;
63     cin >> n >> m >> k ;
64     for( int i = 0 ,u,v,w ; i < m ; i++ ){
65         cin >> u >> v >> w ;
66         for( int j = 0 ; j <= k ; j++ ){
67             Add_Edge( u + (j*n) , v + (j*n) , w );
68             Add_Edge( v + (j*n) , u + (j*n) , w );
69             if( j < k ){
70                 Add_Edge( u + j*n ,  v + (j+1)*n , w>>1 );
71                 Add_Edge( v + j*n ,  u + (j+1)*n , w>>1 );
72             }
73         }
74     }
75     Dijstra();
76     int ans = 0x3f3f3f3f ;
77     for( int i = 0 ; i <= k ; i++ ){
78         ans = min( ans , dis[n+i*n] ) ;
79     }
80     cout << ans << endl ;
81     return 0;
82 }
View Code

P2176 [USACO14FEB]路障Roadblock

  1 #include<cstdio>
  2 #include<cctype>
  3 #include<cstring>
  4 #include<queue>
  5 #include<algorithm>
  6 using namespace std;
  7 const int N=1e5+10;
  8 const int M = 255;
  9 inline void read(int &x){
 10     int ans=0,f=1;
 11     char c=getchar();
 12     for(;!isdigit(c);c=getchar()){
 13         if(c=='-')
 14             f=-1;
 15     }
 16     for(;isdigit(c);c=getchar()){
 17         ans=ans*10+c-'0';
 18     }
 19     x=ans*f;
 20 }
 21  
 22 typedef struct Edge{
 23     int to,next,w;
 24 }Edge;
 25  
 26 Edge edge[N];
 27 Edge e[N] ;
 28 int cnt,head[M],dis[M];
 29 int Cnt,Head[M],Dis[M];
 30 int n,m;
 31  
 32 void add_edge(int u,int v,int w){
 33     edge[cnt].to=v;
 34     edge[cnt].w=w;
 35     edge[cnt].next=head[u];
 36     head[u]=cnt++;
 37 }
 38 void Add_edge(int u,int v,int w){
 39     e[Cnt].to=v;
 40     e[Cnt].w=w;
 41     e[Cnt].next=Head[u];
 42     Head[u]=Cnt++;
 43 }
 44  
 45 typedef struct Cmp{
 46     bool operator () (const int &p1,const int &p2){
 47         return dis[p1]<dis[p2];
 48     }
 49 }Cmp;
 50  
 51 typedef struct cmp{
 52     bool operator () (const int &p1,const int &p2){
 53         return Dis[p1]<Dis[p2];
 54     }
 55 }cmp;
 56  
 57 int Dijstra(int k);
 58 int dijstra(int k){
 59     memset(dis,0x3f,sizeof(dis));
 60     dis[k]=0;
 61     priority_queue< int ,vector<int> , Cmp > q;
 62     q.push(k);
 63  
 64     while(!q.empty()){
 65         int u=q.top();
 66         q.pop();
 67         for(int i=head[u];~i;i=edge[i].next){
 68             int v=edge[i].to;
 69             if(dis[v]>dis[u]+edge[i].w){
 70                 dis[v]=dis[u]+edge[i].w;
 71                 q.push(v);
 72             }
 73         }
 74     }
 75  
 76     //printf("%d\n",dis[n]);
 77  
 78     int W = 0 ;
 79     for(int u=1;u<=n;u++){
 80         for(int i=head[u];~i;i=edge[i].next){
 81             if( dis[u] + edge[i].w == dis[edge[i].to] ){
 82                 //printf(" %d , %d  = %d \n",u,edge[i].to,edge[i].w);
 83                 Add_edge(u,edge[i].to,edge[i].w);
 84                 //Add_edge(edge[i].to,u,edge[i].w);
 85                 W = max ( W , edge[i].w );
 86             }
 87         }
 88     }
 89  
 90     for(int u=1;u<=n;u++){
 91         for(int i=head[u];~i;i=edge[i].next){
 92             if( dis[u] + edge[i].w != dis[edge[i].to] && dis[u] + edge[i].w - W <= dis[edge[i].to]){
 93                 //printf(" %d , %d  = %d \n",u,edge[i].to,edge[i].w);
 94                 Add_edge(u,edge[i].to,edge[i].w);
 95                 //Add_edge(edge[i].to,u,edge[i].w);
 96             }
 97         }
 98     }
 99  
100     int tmp = dis[n];
101     int maxz = dis[n];
102     for(int u=1;u<=n;u++){
103         for(int i=Head[u];~i;i=e[i].next){
104             //printf(" %d , %d  = %d \n",u,e[i].to,e[i].w);
105             e[i].w = e[i].w * 2;
106             //e[i^1].w = e[i^1].w * 2 ;
107             maxz = max(Dijstra(1),maxz);
108             e[i].w = e[i].w / 2;
109             //e[i^1].w = e[i^1].w / 2 ;
110         }
111     }
112     return maxz - tmp ;
113  
114 }
115 int Dijstra(int k) {
116     memset(Dis, 0x3f, sizeof(Dis));
117     Dis[k] = 0;
118     priority_queue<int, vector<int>, cmp> q;
119     q.push(k);
120     //printf("### %d\n",Dis[0]);
121     while (!q.empty()) {
122         int u = q.top();
123         q.pop();
124         for (int i = Head[u]; ~i; i = e[i].next) {
125             int v = e[i].to;
126             if (Dis[v] > Dis[u] + e[i].w) {
127                 Dis[v] = Dis[u] + e[i].w;
128                 q.push(v);
129                 //printf(" Dis[%d] , %d\n",v,Dis[v]);
130             }
131         }
132     }
133     //printf("### %d\n",Dis[n]);
134     return Dis[n];
135 }
136 int main()
137 {
138     memset(Head,-1,sizeof(Head));
139     memset(head,-1,sizeof(head));
140     scanf("%d%d",&n,&m);
141  
142     for(int i=0,u,v,w;i<m;i++){
143         read(u),read(v),read(w);
144         add_edge(u,v,w);
145         add_edge(v,u,w);
146     }
147     printf("%d\n",dijstra(1));
148  
149     return 0;
150 }
View Code

P2939 [USACO09FEB]改造路Revamping Trails

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N = 4e6+10;
 4 const int M = 4e6+10;
 5 
 6 typedef struct Edge{
 7     int to , next , w ;
 8 }Edge ;
 9 Edge e[M<<1] ;
10 
11 typedef struct Node{
12     int u , w ;
13     Node( int _u = 0 , int _w = 0 ):u(_u),w(_w){}
14     bool operator < ( const Node &rhs ) const {
15         return w > rhs.w ;
16     }
17 }Node;
18 
19 int head[N] , idx ;
20 void Add_Edge( int u , int v , int w ){
21     e[idx] = Edge{ v , head[u] , w };
22     head[u] = idx ++ ;
23 }
24 
25 int dis[N] , vis[N] ;
26 int n , m , k ;
27 
28 void Init(){
29     memset( head , -1 , sizeof head );
30     idx = 0 ;
31 }
32 
33 void Dijstra(){
34     memset( dis , 0x3f , sizeof dis );
35     memset( vis , 0 , sizeof vis );
36 
37     dis[1] = 0 ;
38     priority_queue < Node > Q;
39     Q.push( Node(1,0) ) ;
40     while( !Q.empty() ){
41         Node cur = Q.top() ;
42         Q.pop() ;
43         int u = cur.u ;
44         if( vis[u] ) continue ;
45         vis[u] = 1 ;
46 
47         for( int i = head[u] ; ~i ; i = e[i].next ){
48             int To = e[i].to ;
49             int w = e[i].w ;
50             if( dis[To] > dis[u] + w ){
51                 dis[To] = dis[u] + w ;
52                 Q.push( Node( To, dis[To] ) );
53             }
54         }
55     }
56 }
57 
58 int main()
59 {
60     ios_base :: sync_with_stdio(false);
61     cin.tie(NULL) , cout.tie(NULL) ;
62     Init() ;
63     cin >> n >> m >> k ;
64     for( int i = 0 ,u,v,w ; i < m ; i++ ){
65         cin >> u >> v >> w ;
66         for( int j = 0 ; j <= k ; j++ ){
67             Add_Edge( u + (j*n) , v + (j*n) , w );
68             Add_Edge( v + (j*n) , u + (j*n) , w );
69             if( j < k ){
70                 Add_Edge( u + j*n ,  v + (j+1)*n , 0 );
71                 Add_Edge( v + j*n ,  u + (j+1)*n , 0 );
72             }
73         }
74     }
75     Dijstra();
76     int ans = 0x3f3f3f3f ;
77     for( int i = 0 ; i <= k ; i++ ){
78         ans = min( ans , dis[n+i*n] ) ;
79     }
80     cout << ans << endl ;
81     return 0;
82 }
View Code

南京网络赛 Magical Girl Haze

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N = 3200010;
 5 const int M = 5400000;
 6 int n,m,k;
 7 typedef struct Edge{
 8     int to , next ;
 9     ll w ;
10 }Edge;
11 Edge e[M];
12 
13 typedef struct Node{
14     int u ;
15     ll w ;
16     Node ( int _u = 0 , ll _w = 0 ):u(_u),w(_w){}
17     bool operator < ( const Node & rhs ) const {
18         return w > rhs.w ;
19     }
20 }Node;
21 
22 int head[N],idx;
23 void Add_edge( int u, int v ,ll w ){
24     e[idx] = Edge { v , head[u] , w };
25     head[u] = idx ++ ;
26 }
27 
28 void Init(){
29     memset( head , -1 , sizeof head );
30     idx = 0 ;
31 }
32 
33 ll dis[N];
34 bool vis[N];
35 
36 void Dijstra(){
37     memset( dis , 0x3f , sizeof dis );
38     memset( vis , 0  , sizeof vis );
39 
40     dis[1] = 0 ;
41     priority_queue<Node> Q;
42     Q.push( Node(1,0) );
43 
44     while( !Q.empty() ){
45         Node cur = Q.top();
46         Q.pop();
47         int u = cur.u ;
48         if( vis[u] ) continue ;
49         vis[u] = 1 ;
50 
51         for( int i = head[u] ; ~i ; i = e[i].next ){
52             int to = e[i].to , w = e[i].w ;
53             if( dis[to] > dis[u] + w ){
54                 dis[to] = dis[u] + w ;
55                 Q.push( Node(to,dis[to]) );
56             }
57         }
58     }
59 }
60 int main()
61 {
62     int T;
63     scanf("%d",&T);
64     while(T--){
65         Init();
66         scanf("%d%d%d",&n,&m,&k);
67         for( int i = 0 ; i < m ; i++ ){
68             int u , v ; ll w ;
69             scanf("%d%d%lld",&u,&v,&w);
70             for( int j = 0 ; j <= k ; j++ ){
71                 Add_edge( u + ( j*n ), v + j*n , w );
72                 if( j < k ){
73                     Add_edge( u + j * n , v + (j+1)*n , 0 );
74                 }
75             }
76         }
77         Dijstra();
78         printf("%lld\n",dis[n*(k+1)]);
79     }
80     return 0;
81 }
View Code

2019牛客多校 第四场 J_free

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N = 3200010;
 5 const int M = 5400000;
 6 int n,m,k;
 7 typedef struct Edge{
 8     int to , next ;
 9     ll w ;
10 }Edge;
11 Edge e[M];
12 
13 typedef struct Node{
14     int u ;
15     ll w ;
16     Node ( int _u = 0 , ll _w = 0 ):u(_u),w(_w){}
17     bool operator < ( const Node & rhs ) const {
18         return w > rhs.w ;
19     }
20 }Node;
21 
22 int head[N],idx;
23 void Add_edge( int u, int v ,ll w ){
24     e[idx] = Edge { v , head[u] , w };
25     head[u] = idx ++ ;
26 }
27 
28 void Init(){
29     memset( head , -1 , sizeof head );
30     idx = 0 ;
31 }
32 
33 ll dis[N];
34 bool vis[N];
35 
36 void Dijstra(int S){
37     memset( dis , 0x3f , sizeof dis );
38     memset( vis , 0  , sizeof vis );
39 
40     dis[S] = 0 ;
41     priority_queue<Node> Q;
42     Q.push( Node(S,0) );
43 
44     while( !Q.empty() ){
45         Node cur = Q.top();
46         Q.pop();
47         int u = cur.u ;
48         if( vis[u] ) continue ;
49         vis[u] = 1 ;
50 
51         for( int i = head[u] ; ~i ; i = e[i].next ){
52             int to = e[i].to , w = e[i].w ;
53             if( dis[to] > dis[u] + w ){
54                 dis[to] = dis[u] + w ;
55                 Q.push( Node(to,dis[to]) );
56             }
57         }
58     }
59 }
60 int main()
61 {
62     int S,T;
63     Init();
64     scanf("%d%d%d%d%d",&n,&m,&S,&T,&k);
65     for( int i = 0 ; i < m ; i++ ){
66         int u , v ; ll w ;
67         scanf("%d%d%lld",&u,&v,&w);
68         for( int j = 0 ; j <= k ; j++ ){
69             Add_edge( u + ( j*n ), v + j*n , w );
70             Add_edge( v + ( j*n ), u + j*n , w );
71             if( j < k ){
72                 Add_edge( u + j * n , v + (j+1)*n , 0 );
73                 Add_edge( v + j * n , u + (j+1)*n , 0 );
74             }
75         }
76     }
77     Dijstra(S);
78     ll ans = 0x3f3f3f3f3f3f3f3f;
79     for( int i = 0 ; i <= k ; i++ ){
80         ans = min( ans , dis[T+(i*n)] );
81     }
82     printf("%lld\n",ans);
83     return 0;
84 }
View Code

猜你喜欢

转载自www.cnblogs.com/Osea/p/11568909.html