「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 }
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 }
工欲善其事 必先利其器