poj-3662 Telephone Lines

呂振麒 bio photo By 呂振麒 Comment

傳送門:

Telephone Lines

題意:

從第1點走到第N點(不必經過所有點)經過的邊,權重最大的儘量小,並且有K條道路可當作權重為0,求最大權重。

思路:

二分搜最大權重,跑一個特殊的dijkstra算法,Key值是該點剩餘的K,需注意最後答案可能為0。

code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
int N,P,K, a,b,l, mx;

vii G[1005];
bool visit[1005];
void init(){
  N = getint(), P = getint(), K = getint();
  mx = 0;
  while(P--){
    a = getint(), b = getint(), l = getint();
    mx = max(mx, l);
    G[a].PB(MP(b,l));
    G[b].PB(MP(a,l));
  }
}

typedef priority_queue<pii> pq;
pq q;
int karr[1005];

inline bool suc(int x){
  memset(visit, 0, sizeof(visit));
  fill(karr, karr+N+1, -INT_MAX);
  q = pq();
  karr[1] = K;
  q.push(MP(K,1));
  while(!q.empty()){
    int k = q.top().X, v = q.top().Y;
    q.pop();
    if(visit[v]) continue;
    visit[v] = 1;
    for(int i=0;i<G[v].size();i++){
      int vv = G[v][i].X, len = G[v][i].Y;
      if(!visit[vv] and ((len<=x and k>karr[vv]) or (k>0 and k-1>karr[vv]))){
        if(vv == N) return true;
        if(len <= x){
          q.push(MP(k, vv));
          karr[vv] = k;
        }
        else{
          q.push(MP(k-1, vv));
          karr[vv] = k-1;
        }
      }
    }
  }
  return false;
}

void sol(){
  visit[1] = 1;
#define mid ((L+R)>>1)
  int L = -1, R = mx;   // 注意L為-1才能做到 suc(0) 的case
  if(!suc(mx)){
    puts("-1");
    return;
  }
  while(R-L>1) suc(mid) ? R=mid : L=mid;
  cout << R << endl;
}

int main(){
  init();
  sol();
}
comments powered by Disqus