刚开始一直没能读懂题,后来读懂题了,感觉没什么思路,后来看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 }