「LOJ/一本通 3.2 例 3」架设电话线

输入格式

第一行三个整数 N,P,KN,P,K.

接下来 PP 行,每行三个整数 A_i,B_i,L_iAi,Bi,Li.

输出格式

若不存在从 11 到 NN 的路径,输出 -1。否则输出所需最小费用。

样例输入

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

数据范围

 

题解:

  • 对于 50Pts , 考虑直接暴力搜索.
  • 对于 100Pts , 本题的答案显然存在单调性。因此考虑使用二分+最短路。二分一个Mid值使得花费不超过Mid.我们只需要把价格大于Mid的看为1边,不超过的看为0边,然后求1-N的最短路是否不超过K即可.
  • 似乎还有一种使用动态规划+最短路进行求解的方法,目前还未研究,有兴趣的可以进行了解。

代码片:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<map>
 8 #include<set>
 9 #include<vector>
10 #include<queue>
11 #define Res register
12 #define Inf 1e9
13 const int Num = 2000+200;
14 
15 using namespace std;
16 
17 int N , M , K , An = Inf , Sum = 0;
18 struct Yuns{
19     int X , Y , Z;
20 }Ver[Num];
21 int Ans[Num] , Next[Num*2] , Head[Num*2] , Book[Num] , Que[Num];
22 
23 inline int Read()
24 {
25     int x=0,f=1;char ch=getchar();
26     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
27     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
28     return x*f;
29 }
30 
31 void Add(int X , int Y , int Z){
32     Ver[++Sum].X = X;
33     Ver[Sum].Y = Y;
34     Ver[Sum].Z = Z;
35     Next[Sum] = Head[X];
36     Head[X] = Sum;
37     return;
38 } 
39 
40 void Dfs(int Line , int Step){
41     
42     if (Line == N){
43         for (Res int i = 1 ; i <= Step ; i++) Que[i] = Ans[i];
44         sort(Que+1 , Que+Step+1);
45         An = min(An , Que[Step-K]); 
46         memset(Que , 0 , sizeof(Que));
47         return;
48     }
49     
50     for (Res int i = Head[Line] ; i ; i = Next[i]){
51         int Y = Ver[i].Y;
52         if (!Book[Y]){
53             Book[Y] = 1;
54             Ans[Step] = Ver[i].Z; 
55             Dfs(Y , Step+1);
56             Ans[Step] = 0;
57             Book[Y] = 0;
58         }
59 
60     } 
61     return;
62 }
63 
64 int main(){
65     
66     int A , B , C;
67     N = Read() , M = Read() , K = Read();
68     for (Res int i = 1 ; i <= M ; i++){
69         A = Read() , B = Read() , C = Read();
70         Add(A , B , C) , Add(B , A , C); 
71     }
72     
73     Dfs(1 , 1);
74     
75     if (An == 1e9){
76         cout << -1;
77         return 0;
78     }else cout << An;
79     
80     return 0;
81     
82 }
50Pts
 1 #include <cstdio>
 2 #include <vector>
 3 #include <queue>
 4 #include <algorithm>
 5 using namespace std;
 6 const int inf = 1000 + 10;
 7 const int maxn = 1000 + 10;
 8 const int maxp = 10000 + 10;
 9 const int maxl = 1000000 + 10;
10 typedef pair<int, int> P;
11 struct pole {
12     int b, l;
13     pole() {}
14     pole(int b, int l) : b(b), l(l) {}
15 };
16 vector<pole> G[maxp];
17 int d[maxn];
18 int n, p, k;
19 int Dijkstra(int s, int x) {
20     priority_queue<P, vector<P>, greater<P> > que;
21     fill(d, d + n, inf);
22     d[s] = 0;
23     que.push(P(0, s));
24     while (!que.empty()) {
25         P p = que.top();
26         que.pop();
27         int v = p.second;
28         if (d[v] < p.first)
29             continue;
30         for (int i = 0; i < G[v].size(); i++) {
31             pole e = G[v][i];
32             int nd = d[v] + (e.l > x ? 1 : 0);
33             if (d[e.b] > nd) {
34                 d[e.b] = nd;
35                 que.push(P(d[e.b], e.b));
36             }
37         }
38     }
39     return d[n-1];
40 }
41 int main(int argc, char const *argv[]) {
42     scanf("%d%d%d", &n, &p, &k);
43     for (int i = 0; i < p; i++) {
44         int a, b, l;
45         scanf("%d%d%d", &a, &b, &l);
46         a--, b--;
47         G[a].push_back(pole(b, l));
48         G[b].push_back(pole(a, l));
49     }
50     int lb = 0, ub = maxl;
51     while (ub > lb) {
52         int mid = (lb + ub) / 2;
53         if (Dijkstra(0, mid) > k) {
54             lb = mid + 1;
55         } else {
56             ub = mid;
57         }
58     }
59     if (lb == maxl) {
60         puts("-1");
61     } else {
62         printf("%d\n", ub);
63     }
64     return 0;
65 }
100Pts

 

posted @ 2019-02-13 15:30  Yuns's  阅读(539)  评论(0编辑  收藏  举报