POJ3662:Telephone Lines
URL:http://poj.org/problem?id=3662
——problem:一个无向图有n个点, p条边, 每边有花费, 可以任意指定有k条边免费, 现要求选择若干条边构成顶点1到顶点n的一条路径, 使得路径上边权最大值(不包括免费边)最小.
——solution:二分答案,最短路
假设A是可行解,即路径上边权最大值为A,则该路径上边权大于A的边一定小于等于K条。
若A不是最优解,那么必然B<A,是的路径上边权大于B的边小于等于K。
于是我们可以二分答案,得到一个值X,将所有小于等于X的边变为0,大于X的边变为1。
做最短路,则1到N的距离就是所用权值大于X边的条数。如果小于等于K,则是一个可行解。
————————————————————————————————————————————————————————————————————————
View Code
1 #include<stdio.h>
2 #include<queue>
3 using namespace std;
4 #define E 40000
5 #define V 1005
6 #define typec int
7 const typec inf = 0x3f3f3f3f;
8 typec cost[E], dist[V];
9 int n,m,k,e,ans,top;
10 int pnt[E], nxt[E], head[V], vis[V],len[E];
11 struct qnode
12 {
13 int v;
14 typec c;
15 qnode(int vv = 0, typec cc = 0) :
16 v(vv), c(cc)
17 {
18 }
19 bool operator <(const qnode& r) const
20 {
21 return c > r.c;
22 }
23 };
24 int cmp(const void *a,const void *b)
25 {
26 return *(int *)a-*(int *)b;
27 }
28 int dijkstra(int n, const int src,int maxlen)
29 {
30 qnode mv;
31 int i, j, k, pre,temp_len;
32 priority_queue<qnode> que;
33 memset(vis, 0, sizeof(vis));
34 for (i = 1; i <= n; i++)
35 dist[i] = inf;
36 vis[src] = 1;
37 dist[src] = 0;
38 que.push(qnode(src, 0));
39 for (pre = src, i = 1; i < n; i++)
40 {
41 for (j = head[pre]; j != -1; j = nxt[j])
42 {
43 k = pnt[j];
44 if (cost[j]>maxlen)
45 temp_len=1;
46 else temp_len=0;
47 if (vis[k] == 0 && dist[pre] + temp_len < dist[k])
48 {
49 dist[k] = dist[pre] +temp_len;
50 que.push(qnode(pnt[j], dist[k]));
51 }
52 }
53 while (!que.empty() && vis[que.top().v] == 1)
54 que.pop();
55 if (que.empty())
56 break;
57 mv = que.top();
58 que.pop();
59 vis[pre = mv.v] = 1;
60 }
61 return dist[n];
62 }
63 inline void addedge(int u, int v, typec c)
64 {
65 pnt[e] = v;
66 cost[e] = c;
67 nxt[e] = head[u];
68 head[u] = e++;
69 }
70 int main()
71 {
72 int i, j, u, v,l,r,mid,temp;
73 typec c;
74 memset(head, -1, sizeof(head));
75 memset(nxt, -1, sizeof(nxt));
76 e = 0;
77 scanf("%d%d%d",&n,&m,&k);
78 len[top=0]=0;
79 for (i=0;i<m;i++)
80 {
81 scanf("%d%d%d",&u,&v,&c);
82 addedge(u,v,c);
83 addedge(v,u,c);
84 top++;
85 len[top]=c;
86 }
87 qsort(len,top+1,sizeof(len[0]),cmp);
88 j=0;
89 for (i=1;i<=top;i++)
90 if (len[i]!=len[j])
91 len[++j]=len[i];
92 l=0;
93 r=j;
94 ans=-1;
95 while (l<=r)
96 {
97 mid=(l+r)/2;
98 temp=dijkstra(n,1,len[mid]);
99 if (temp<=k)
100 {
101 r=mid-1;
102 ans=len[mid];
103 }
104 else
105 l=mid+1;
106 }
107 printf("%d\n",ans);
108 return 0;
109 }