白駿-139号重量制限
5565 ワード
質問する
複数の島と重量制限のある橋がある場合
ある工場がある島から、別の工場がある島に移せるものの最大重量を求めます.
の意見を打診
ある工場がある島から、別の工場がある島を探索
時間の複雑さ
グラフィック問題の時間的複雑さは確定しにくいので,時間的複雑さを考慮したほうがよい.
島は最大10000個、橋は最大100000個
島はずっと1文字に並んでいて、工場は島の果てと果てにあり、
島の間に10の橋があるとしたら
島を渡るたびに10種類の状況があるからだ.
10^10000はとても大きいです
うん、だから私たちはただ振り返って、最大重量を求めることができないことを知っています.
タイムアウトのアイデア
だから私は
これまでのアクセス経路の最大重量は、通過する橋の最低重量制限であった.
ナビゲーション中に、島を通過するときに可能な最大重量を格納できます.
もう一つのルートで訪問した島にアクセスすると
以前に訪れた重量よりも重量が大きい場合にのみ,さらなる探索を行う.
より小さな重さは過ぎても正解にはなりません.
同じ大きさの重さがリピートナビ~!!!
うーん、これで処理するとタイムアウトしません(パチパチ)
私は心を込めて実現したが、タイムアウトした.
実装方法は次のとおりです.
//큐에 공장이 있는 한 섬(i1)을 넣어놓음
while (!q.empty()){
int nownode = q.front().first;
int nowweight = q.front().second;
q.pop();
//이미 다른 공장 섬(i2)에 도착했다면, 그 중량보다 큰 애들만 탐색하쟈
if (nowweight <= check[i2]) {
continue;
}
for (int i = 0; i < info[nownode].size(); i++) {
int nextnode = info[nownode][i].first;
int nextweight = info[nownode][i].second;
//가능한 최대 중량은 지나온 다리들 중 제일 낮은 중량제한만큼
nextweight = nowweight < nextweight ? nowweight : nextweight;
//가봤자인 애들은 더 탐색 안 할랭
if (nextweight <= check[i2] || check[nownode] == check[nextnode]) {
continue;
}
//그전에 방문했던 중량보다 더 큰 중량으로 오는 경우에만 더 탐색
if (check[nextnode] < nextweight) {
check[nextnode] = nextweight;
if (nextnode != i2) {
q.push(make_pair(nextnode, nextweight));
}
}
}
}
頭が完全に動く
うーん、これは素晴らしいアルゴリズムだと思いますが、タイムアウトしました.
何がこんなに長い間
彼は私にそばで最悪の状況を考えさせて、私は考えました.
う~ん、前に通ったルートよりよかったら行かせてください.
幸いなことに、私たちはまずできるだけ小さい子供たちを見つけました.
たとえ私がこのようにびっこを引いてifを処理しても、私は過去の状況があることを知っています.
(一つの島は最重で2過去、3過去、4過去...9過去...)
ああ~それは悲しいことだ
私はこのアルゴリズムを放棄することができないので、もう一度考えます.
あんな大きい子が先に行ったら、小さい子は通れないじゃないか.
(9を過ぎると2度3度4度…みんな探索終了に行けない!)
優先順位キューを使い、できるだけ最大重量の経路を探索します
そして~~~!~そう、へへへ
+私は彼にこの方法が何なのかと聞いたが、彼はbfs/dfsのような方法ではないと言った.プリンセスじゃないし.
優先順位キューが書かれたグラフを参照するだけです...彼は言った
++優先キューのpush時の時間複雑度はO(logn)
上記で説明した最悪の場合はO(logmN)くらいでしょうか?
もう少し時間を短縮してもらえますか?
Qでも上のアルゴリズムなら
もし私たちが初めて別の工場に着いたら、それは最大の価値でしょう.
A i 1から、そのままi 2まで返してみました
//새로운 섬을 탐색할 때 i2면 바로 출력하고 끝내~~
if (nextnode != i2) {
q.push(make_pair(nextweight, nextnode));
}
else {
cout << check[i2];
return 0;
}
ああ、間違っています.Q私が来たのは一番大きいと思いましたが、最後の探索の時
低い橋なので、最大重量が非常に小さくなります!
Aでは、i 2に到達したときに見られる最大可能重量がaであれば
Qに残っているメンバーの中ではAのメンバーだけが探索しているのでしょうか?
あ~aじゃない子の中でも答えかも~!~
もう二度と顔を出さないと思います.ほほほ
他の人のアルゴリズム
通常、2分ナビゲーションを使用して、重量として0~10000000の値を選択します.
BFSは工場から工場まで重量で通過できますか?
彼は方法で問題を解決した.
こちらの検索はO(logn)なのでCも早いです.
着いたら止まります.
私たちはすぐに問題を解決することができます.
この探索も心の中に置いておきましょう.
コード#コード#
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
int n, m, i1, i2;
int a, b, c;
int check[10005];
vector<pair<int, int>> info[10005];
priority_queue<pair<int, int>> q;
pair<int, int> tempq;
int main() {
cin >> n >> m;
for (int i = 0; i < m; i++) {
cin >> a >> b >> c;
info[a].push_back(make_pair(c, b));
info[b].push_back(make_pair(c, a));
}
cin >> i1 >> i2;
check[i1] = 1000000005;
q.push(make_pair(1000000005, i1));
while (!q.empty()) {
int nowweight = q.top().first;
int nownode = q.top().second;
q.pop();
if (nowweight <= check[i2]) {
continue;
}
for (int i = 0; i < info[nownode].size(); i++) {
int nextweight = info[nownode][i].first;
int nextnode = info[nownode][i].second;
nextweight = nowweight < nextweight ? nowweight : nextweight;
if (nextweight <= check[i2] || check[nownode] == check[nextnode]) {
continue;
}
if (check[nextnode] < nextweight) {
check[nextnode] = nextweight;
if (nextnode != i2) {
q.push(make_pair(nextweight, nextnode));
}
}
}
}
cout << check[i2];
return 0;
}
Reference
この問題について(白駿-139号重量制限), 我々は、より多くの情報をここで見つけました https://velog.io/@weenybeenymini/백준-1939번-중량제한テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol