More lumber is required(多校10,7th,hdu4396,k条边最短路,二维dijkstra)
-- |
More lumber is required(多校10,7th,hdu4396,k条边最短路,二维dijkstra)
Time
Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)
Total Submission(s): 666 Accepted Submission(s): 286
Problem Description
“More lumber is required” When the
famous warcrafts player Sky wants to build a Central Town, he finds there is
not enough lumber to build his Central Town. So he needs to collect enough
lumber. He lets farmer John to do this work.
There
are several Sawmills have already been built in the world, around them are
large forests. Sawmills are connected by bidirectional roads (a sawmill can be
connected to itself). When he passes a road, he will get 10 lumber and consume
a certain time. Sky needs K lumber. So John needs collect as least K lumber.
Sawmills
are labeled from 1 to N. John initiates at Sawmill S. When he finishes his
work, Sky gives him another work: arrive at Sawmill T, and build the Central
Town. John needs to design his route carefully because Sky wants to build this
Central Town as early as possible. He turns you for help. Please help him
calculate the minimum time he needs to finish this work (collect enough lumber
and build the Central Town). If impossible just print -1.
You
can read the Sample Input and Output for more information.
Input
There are multiply test cases, in each
test case:
The first line is two integers N (1<=N<=5000), M (0<=M<=100000)
represent the number of sawmills and the number of the roads.
The next M line is three integers A B C (1<=A, B<=N; 1<=C<=100),
means there exists a road connected Ath sawmill and Bth
sawmill, and pass this road will cost C time.(The sawmills are labeled from 1
to N).
The last line is three integers S T K (1<=S, T<=N; 0<=K<=500), as
mentioned as description.
Output
For each test case, print the result in a single line.
Sample Input
4 4
1 2 1
2 3 2
1 3 100
3 4 1
1 3 50
Sample Output
7
Author
Wanghang----School of Software Technology, Dalian University of Technology
Source
2012 Multi-University Training Contest 10
Recommend
zhuyuanchen520
2 #include<stack>
3 #include<stdlib.h>
4 #include<iostream>
5 #include<map>
6 #include<queue>
7 #include<set>
8 #include<string.h>
9 #define M 200010
10 #define INF 2139062143
11
12 using namespace std;
13 int p[M] = {0},dist[M][55] = {0};
14 bool use[M][55];
15 int eid = 0,n,m,k,S,T; //k是需要走过的边数
16 struct edge
17 {
18 int v,d,next;
19 }e[M];
20 int min(int a,int b)
21 {
22 return a<b?a:b;
23 }
24
25 void addedge(int s,int t,int d)
26 {
27 e[eid].v = t;
28 e[eid].d = d;
29 e[eid].next = p[s];
30 p[s] = eid++;
31 }
32
33 struct node{
34 int v, d , c;
35 friend bool operator < (node n1, node n2)
36 {
37 return n1.d > n2.d;
38 }
39 node(int a, int b, int cc)
40 {
41 v = a, d = b, c = cc;
42 }
43 };
44 priority_queue<node> q;
45 void dijkstra(int begin)
46 {
47 memset(use, false, sizeof(use));
48 memset(dist, 0x7f, sizeof(dist));
49 while (!q.empty()) q.pop();
50 dist[begin][0] = 0;
51 q.push(node(begin, 0, 0));
52 int mk = INF;
53 while(!q.empty())
54 {
55
56 int v = q.top().v, s = q.top().d,kk = q.top().c;
57 while (use[v][kk])
58 {
59 q.pop();
60 if(q.empty()) break;
61 v = q.top().v, s = q.top().d,kk = q.top().c;
62 }
63 if(q.empty()) break;
64 if(v == T &&kk == k)
65 {
66 break;
67 }
68 q.pop();
69 //cout<<endl;
70 //cout<<++ans<<" "<<v<<" "<<s<<" "<<kk<<endl;
71 use[v][kk] = true;
72
73
74 for (int j = p[v]; j != -1; j = e[j].next)
75 {
76 //cout<<dist[e[j].v][kk+1]<<endl;
77 if(kk+1<=k) //当找到的地方所走的边数<=k时,
78 {
79 if (dist[e[j].v][kk+1] > s + e[j].d && !use[e[j].v][kk+1])
80 {
81 q.push(node(e[j].v, s + e[j].d, kk+1));
82 dist[e[j].v][kk+1] = s + e[j].d;
83 //cout<<v<<"->"<<e[j].v<<" "<<e[j].d+s<<" "<<kk + 1<<endl;
84 }
85 }
86 else //找到的地方所走的边数>k时,设置上限为k更新k即可
87 {
88 if (dist[e[j].v][k] > s + e[j].d && !use[e[j].v][k])
89 {
90 q.push(node(e[j].v, s + e[j].d, k));
91 dist[e[j].v][k] = s + e[j].d;
92 //cout<<v<<"->"<<e[j].v<<" "<<e[j].d+s<<" "<<kk + 1<<endl;
93 }
94 }
95
96 }
97
98 }
99 //cout<<endl;
100 if(dist[T][k]>=INF) cout<<"-1"<<endl;
101 else cout<<dist[T][k]<<endl;
102
103 //cout<<dist[T][k]<<" "<<dist[T][k+1]<<endl;
104 }
105
106 int main()
107 {
108 int i;
109 while(scanf("%d %d",&n,&m)!=EOF)
110 {
111 eid = 0;
112 memset(p,-1,sizeof(p));
113 memset(dist,0x7f,sizeof(dist));
114 memset(use,false,sizeof(use));
115 for(i = 0;i<m;i++)
116 {
117 int u,v,d;
118 scanf("%d%d%d",&u,&v,&d);
119 addedge(u,v,d);
120 addedge(v,u,d);
121 }
122 int kkkk = 0;
123 scanf("%d%d%d",&S,&T,&kkkk);
124 k = kkkk/10;
125 if(kkkk%10 != 0) ++k;
126 dijkstra(S);
127 //for(int j = p[4];j!=-1;j = e[j].next)
128 // cout<<e[j].v<<endl;
129 }
130 return 0;
131 }