pku 3662 Telephone Lines

刚开始一直没能读懂题,后来读懂题了,感觉没什么思路,后来看discuss里面的二分答案,顿时豁然开朗。。。

先把所有的道路排序,二分一条道路,把长度比当前短的赋值为0,把长度比当前大的赋值为1,用最短路判断从1到n的最短路径ans,如果ans>k  再二分比当前

道路长的路径, 否则二分比当前路径短的路径,直到找到一个最短的路径符合条件。。

贴下代码:

  
    
1 # include < stdio.h >
2 # include < string .h >
3 # include < stdlib.h >
4 # define N 1005
5 # define M 10005
6 # define PI 0xfffffff
7   int adj[N][N],visit[N],low[N],n;
8 struct node{
9 int a,b,val;
10 }s[M];
11 int cmp( const void * a, const void * b)
12 {
13 struct node * c = ( struct node * )a;
14 struct node * d = ( struct node * )b;
15 return c -> val - d -> val;
16 }
17 void dij()
18 {
19 int index,min,index1,i;
20 index = 1 ;
21 low[ 1 ] = 0 ;
22 while (index != n)
23 {
24 visit[index] = 1 ;
25 min = PI;
26 for (i = 1 ;i <= n;i ++ )
27 {
28 if (visit[i] == 1 ) continue ;
29 if (adj[index][i] ==- 1 && low[i] == PI) continue ;
30 if (adj[index][i] !=- 1 )
31 {
32 if (low[i] > low[index] + adj[index][i])
33 low[i] = low[index] + adj[index][i];
34 }
35 if (low[i] < min) {min = low[i];index1 = i;}
36 }
37 if (min == PI) break ;
38 index = index1;
39 }
40 }
41 int main()
42 {
43 int i,m,k,a,b,c,right,left,mid,mid1,ans;
44 while (scanf( " %d%d%d " , & n, & m, & k) != EOF)
45 {
46 memset(adj, - 1 , sizeof (adj));
47 for (i = 1 ;i <= m;i ++ )
48 {
49 scanf( " %d%d%d " , & a, & b, & c);
50 s[i].a = a;
51 s[i].b = b;
52 s[i].val = c;
53 adj[a][b] = adj[b][a] = 1 ;
54 }
55 qsort(s + 1 ,m, sizeof (s[ 1 ]),cmp);
56 s[ 0 ].val = 0 ;
57 mid1 = 0 ;
58 right = m;left = 0 ;
59 ans =- 1 ;
60 while (right >= left)
61 {
62 mid = (right + left) / 2 ;
63 if (mid1 <= mid)
64 {
65 for (i = mid1;i <= mid;i ++ )
66 adj[s[i].a][s[i].b] = adj[s[i].b][s[i].a] = 0 ;
67 }
68 else
69 {
70 for (i = mid + 1 ;i <= mid1;i ++ )
71 adj[s[i].a][s[i].b] = adj[s[i].b][s[i].a] = 1 ;
72 }
73 mid1 = mid;
74 /*
75 for(i=0;i<=mid;i++)
76 adj[s[i].a][s[i].b]=adj[s[i].b][s[i].a]=0;
77 for(i=mid+1;i<=m;i++)
78 adj[s[i].a][s[i].b]=adj[s[i].b][s[i].a]=1; */
79 for (i = 0 ;i <= n;i ++ )
80 {
81 low[i] = PI;
82 visit[i] = 0 ;
83 }
84 dij();
85 if (low[n] > k) left = mid + 1 ;
86 else {ans = mid;right = mid - 1 ;}
87 }
88 if (ans ==- 1 ) printf( " -1\n " );
89 else printf( " %d\n " ,s[ans].val);
90 }
91 return 0 ;
92 }

你可能感兴趣的:(pku)