洛谷P2387 魔法森林

2022-05-20 12:04:39 字數 1682 閱讀 9510

題目大意:給定乙個 n 個點,m 條邊的無向圖,邊有兩個邊權 a, b,求從 1 號節點到 n 號節點路徑的兩個權值和的最大值最小是多少。

題解:對於有兩個屬性的結構的最優化問題,可以考慮先按照其中乙個分量進行排序。接著從小到大列舉這個有序的分量,計算以當前列舉到的值為這一分量的最大值時,全域性的最優解是多少。因此,需要高效維護的是如何求出另乙個分量的最優解。

對於這道題來說,考慮對 a 分量進行排序,並按從小到大的順序依次加邊。對於即將加入的第 i 條邊來說,若加入這條邊使得兩個本來不聯通的點聯通,則直接加入;若加入這條邊之後,形成了環,則比較加入這條邊 b 的權值和這條邊兩個端點之間路徑上 b 的最大值,若當前邊的 b 更小,則斷開路徑上最大邊權的邊,並加入當前這條邊即可。利用 lct 進行維護 b 即可。

**如下

#include using namespace std;

struct edge

};struct node

void unsafe_reverse()

void pull()

if (r != null)

} void push()

if (r != null)

rev = 0;

} }};bool is_root(node* v)

return (v->p == null) || (v->p->l != v && v->p->r != v);

}void rotate(node* v)

if (v->p->r == u)

} if (v == u->l)

if (v == u->r)

u->pull();

v->pull();

}void deal_with_push(node* v)

v = v->p;

} while (!s.empty())

}void splay(node* v) else

} rotate(v); }}

void access(node* v)

}void make_root(node* v)

node* find_root(node* v)

splay(v);

return v;

}void link(node* v, node* u)

}void cut(node* v, node* u)

}void split(node* v, node* u)

node* find(node* v, int b)

if (v->l != null && v->l->maxb == b) else

} return v;

}int main()

sort(e.begin(), e.end(), [&](const edge &x, const edge &y) );

vectort(n + m);

for (int i = 0; i < n; i++)

int ans = 1e9;

for (int i = 0; i < m; i++) else

} if (find_root(t[0]) == find_root(t[n - 1]))

} if (ans == 1e9) else

return 0;

}

洛谷 P2387 魔法森林

題目描述 為了得到書法大家的真傳,小 e 同學下定決心去拜訪住在魔法森林中的隱 士。魔法森林可以被看成乙個包含 n 個節點 m 條邊的無向圖,節點標號為 1,2,3,n,邊標號為 1,2,3,m。初始時小 e 同學在 1 號節點,隱士則住在 n 號節點。小 e 需要通過這一片魔法森林,才能夠拜訪到隱...

洛谷 P2387 魔法森林

為了得到書法大家的真傳,小 e 同學下定決心去拜訪住在魔法森林中的隱 士。魔法森林可以被看成乙個包含 n 個節點 m 條邊的無向圖,節點標號為 1,2,3,n,邊標號為 1,2,3,m。初始時小 e 同學在 1 號節點,隱士則住在 n 號節點。小 e 需要通過這一片魔法森林,才能夠拜訪到隱士。魔法森...

洛谷P2387 魔法森林 spfa

為了得到書法大家的真傳,小 e 同學下定決心去拜訪住在魔法森林中的隱 士。魔法森林可以被看成乙個包含 n 個節點 m 條邊的無向圖,節點標號為 1,2,3,n,邊標號為 1,2,3,m。初始時小 e 同學在 1 號節點,隱士則住在 n 號節點。小 e 需要通過這一片魔法森林,才能夠拜訪到隱士。魔法森...