poj 3662 Telephone Lines

Great question. In simple terms, this question is to find a path from 1 to N on an undirected graph such that the K + 1th largest edge weight on the path is as small as possible.

The answer to this question is obviously monotonic. When paying more money, a legitimate upgrade plan must include a plan with less call charges.

So consider bisection. Set the length of the edge whose upgrade price does not exceed mid as 0, and then find out whether the length of the shortest path from 1 to N does not exceed K.

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <cstring>
  4 #include <queue>
  5 #include <vector>
  6 #include <iostream>
  7 
  8 using namespace std;
  9 typedef pair<int, int> Pa;
 10 const int MAXN = 1e3 + 20;
 11 const int MAXP = 1e4 + 20;
 12 const int MAXL = 1000000 + 20;
 13 
 14 inline int read()
 15 {
 16     int x = 0; char ch = getchar();
 17     while(!isdigit(ch)) ch = getchar();
 18     while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
 19     return x;
 20 }
 21 
 22 int N, P, K;
 23 
 24 namespace edges
 25 {
 26     struct edge
 27     {
 28         int from, to, cost;
 29         edge(int u = 0, int v = 0, int c = 0) : from(u), to(v), cost(c) {}
 30 
 31         bool operator <(const edge &rhs) const{
 32             return cost < rhs.cost;
 33         }
 34     }E[MAXP];
 35 
 36     inline void addedge(int u, int v, int c)
 37     {
 38         static int cnt = 1;
 39         E[cnt++] = edge(u, v, c);
 40     }
 41 
 42     inline void init()
 43     {
 44         sort(E + 1, E + P + 1);
 45     }
 46 }
 47 
 48 namespace dij
 49 {
 50     struct edge
 51     {
 52         int to, cost;
 53         edge(int v = 0, int c = 0) : to(v), cost(c) {}
 54     };
 55 
 56     vector<edge> g[MAXN];
 57     int d[MAXN];
 58 
 59     inline void addedge(int u, int v, int c)
 60     {
 61         g[u].push_back(edge(v, c));
 62         g[v].push_back(edge(u, c));
 63     }
 64 
 65     inline void init()
 66     {
 67         for(int i = 0; i <= N; i++)
 68             g[i].clear();
 69     }
 70 
 71     inline bool tension(const int &sml, int &big)
 72     {
 73         return sml < big ? (big = sml, true) : false;
 74     }
 75 
 76     inline int dijkstra(int s, int t)
 77     {
 78         deque<Pa> q;
 79         memset(d, 0x3f, sizeof(d));
 80 
 81         d[s] = 0;
 82         q.push_front(Pa(0, s));
 83 
 84         while(!q.empty())
 85         {
 86             Pa p = q.front(); q.pop_front();
 87             int u = p.second;
 88             if(d[u] < p.first) continue;
 89 
 90             for(int i = 0; i < (int) g[u].size(); i++)
 91             {
 92                 edge e = g[u][i];
 93                 if(tension(d[u] + e.cost, d[e.to]))
 94                 {
 95                     if(e.cost == 1) q.push_back(Pa(d[e.to], e.to));
 96                     else q.push_front(Pa(d[e.to], e.to));
 97                 }
 98             }
 99         }
100         return d[t];
101     }
102 }
103 
104 inline bool check(int fare)
105 {
106     using namespace edges;
107 
108     dij::init();
109     for(int i = 1; i <= P; i++)
110     {
111         edge e = E[i];
112         dij::addedge(e.from, e.to, e.cost > fare ? 1 : 0);
113     }
114 
115     return dij::dijkstra(1, N) > K ? false : true;
116 }
117 
118 int main()
119 {
120 //    freopen("p1948.txt", "r", stdin);
121     cin>>N>>P>>K;
122 
123     int u, v;
124     for(int i = 1; i <= P; i++)
125     {
126         u = read(), v = read();
127         edges::addedge(u, v, read());
128     }
129 
130     //edges::init();
131 
132     int l = 0, r = MAXL;
133     #define mid (((l) + (r)) >> 1)
134     while(l < r)
135     {
136         if(check(mid)) r = mid;
137         else l = mid + 1;
138     }
139 
140     if(l == MAXL) cout<<-1<<endl;
141     else cout<<l<<endl;
142     return 0;
143 }

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325378357&siteId=291194637