結果
| 問題 |
No.416 旅行会社
|
| コンテスト | |
| ユーザー |
はむ吉🐹
|
| 提出日時 | 2016-08-27 20:48:07 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 643 ms / 4,000 ms |
| コード長 | 3,682 bytes |
| コンパイル時間 | 1,289 ms |
| コンパイル使用メモリ | 95,520 KB |
| 実行使用メモリ | 50,188 KB |
| 最終ジャッジ日時 | 2024-12-14 20:05:20 |
| 合計ジャッジ時間 | 8,559 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 21 |
ソースコード
#include <algorithm>
#include <ciso646>
#include <cstdlib>
#include <iostream>
#include <numeric>
#include <set>
#include <vector>
#include <unordered_set>
#include <utility>
typedef std::pair<int, int> Edge;
class DisjointDataStructure {
public:
DisjointDataStructure(int number_of_nodes) {
par = std::vector<int>(number_of_nodes);
std::iota(par.begin(), par.end(), 0);
rank = std::vector<int>(number_of_nodes);
groups = std::vector<std::unordered_set<int>>(number_of_nodes);
for (int i = 0; i < number_of_nodes; i++)
{
groups[i].insert(i);
}
}
int root(int node) {
if (par[node] == node)
{
return node;
}
else
{
return par[node] = root(par[node]);
}
}
inline bool inTheSameSet(int node1, int node2) {
return root(node1) == root(node2);
}
inline std::unordered_set<int> group(int x) {
return groups[root(x)];
}
void unite(int node1, int node2) {
auto x = root(node1);
auto y = root(node2);
if (x == y)
{
return;
}
else if (rank[x] < rank[y])
{
par[x] = y;
groups[y].insert(groups[x].begin(), groups[x].end());
groups[x].clear();
}
else
{
par[y] = x;
groups[x].insert(groups[y].begin(), groups[y].end());
groups[y].clear();
if (rank[x] == rank[y])
{
rank[x]++;
}
}
}
private:
std::vector<int> par;
std::vector<int> rank;
std::vector<std::unordered_set<int>> groups;
};
std::vector<int> solve(int n, int q, const std::set<Edge>& all_edges,
const std::vector<Edge>& removed_edges) {
auto removed_edges_set = std::set<Edge>(removed_edges.begin(), removed_edges.end());
auto uf = DisjointDataStructure(n);
constexpr int root = 0;
auto con_time = std::vector<int>(n);
for (const auto& edge : all_edges)
{
if (removed_edges_set.count(edge) == 0)
{
uf.unite(edge.first, edge.second);
}
}
for (int i = 1; i < n; i++)
{
if (uf.inTheSameSet(root, i))
{
con_time[i] = -1;
}
}
for (int i = q - 1; i >= 0; i--)
{
auto source = removed_edges[i].first;
auto dest = removed_edges[i].second;
if (not uf.inTheSameSet(source, dest))
{
auto bs = uf.inTheSameSet(root, source);
auto bd = uf.inTheSameSet(root, dest);
if (bs or bd)
{
if (bd)
{
std::swap(source, dest);
}
for (const auto& v : uf.group(dest))
{
con_time[v] = i + 1;
}
}
uf.unite(source, dest);
}
}
return con_time;
}
int main() {
std::cin.tie(nullptr);
std::ios::sync_with_stdio(false);
int n, m, q;
std::cin >> n >> m >> q;
std::set<Edge> all_edges;
for (int i = 0; i < m; i++)
{
int a, b;
std::cin >> a >> b;
a--;
b--;
all_edges.insert(std::make_pair(a, b));
}
std::vector<Edge> removed_edges;
for (int i = 0; i < q; i++)
{
int c, d;
std::cin >> c >> d;
c--;
d--;
removed_edges.push_back(std::make_pair(c, d));
}
auto con_time = solve(n, q, all_edges, removed_edges);
for (int i = 1; i < n; i++)
{
std::cout << con_time[i] << std::endl;
}
return EXIT_SUCCESS;
}
はむ吉🐹