結果
| 問題 |
No.1983 [Cherry 4th Tune C] 南の島のマーメイド
|
| コンテスト | |
| ユーザー |
milanis48663220
|
| 提出日時 | 2022-06-17 22:27:31 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 521 ms / 4,000 ms |
| コード長 | 4,490 bytes |
| コンパイル時間 | 1,489 ms |
| コンパイル使用メモリ | 127,100 KB |
| 最終ジャッジ日時 | 2025-01-29 22:18:51 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 41 |
ソースコード
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <tuple>
#include <cmath>
#include <numeric>
#include <functional>
#include <cassert>
#define debug_value(x) cerr << "line" << __LINE__ << ":<" << __func__ << ">:" << #x << "=" << x << endl;
#define debug(x) cerr << "line" << __LINE__ << ":<" << __func__ << ">:" << x << endl;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
using namespace std;
typedef long long ll;
template<typename T>
vector<vector<T>> vec2d(int n, int m, T v){
return vector<vector<T>>(n, vector<T>(m, v));
}
template<typename T>
vector<vector<vector<T>>> vec3d(int n, int m, int k, T v){
return vector<vector<vector<T>>>(n, vector<vector<T>>(m, vector<T>(k, v)));
}
template<typename T>
void print_vector(vector<T> v, char delimiter=' '){
if(v.empty()) {
cout << endl;
return;
}
for(int i = 0; i+1 < v.size(); i++) cout << v[i] << delimiter;
cout << v.back() << endl;
}
using P = pair<int, int>;
struct edge{
int from, to;
edge(int from, int to): from(from), to(to) {}
};
/**
* dfs木上の後退辺に対応するpathをimos法で塗っていく
* 塗られなかった辺が橋となる
* verified by ARC039 D
*/
class TwoEdgeConnectedComponents{
public:
TwoEdgeConnectedComponents(vector<edge> v, int size){
G = vector<vector<int>>(size);
used = vector<bool>(size, false);
col = vector<int>(size, 0);
depth = vector<int>(size, 0);
for(edge e : v){
int from = e.from;
int to = e.to;
G[from].push_back(to);
G[to].push_back(from);
}
N = size;
}
vector<vector<int>> G;
int N;
vector<edge> run(){
vector<edge> bridges;
dfs(0, -1, 0);
clear();
paint(0, -1, bridges);
return bridges;
}
private:
vector<bool> used;
vector<int> col;
vector<int> depth;
void dfs(int u, int p, int d){
used[u] = true;
depth[u] = d;
for(int to : G[u]){
if(to == p) continue;
if(used[to] && depth[to] < depth[u]){
col[u]++;
col[to]--;
}else if(!used[to]){
dfs(to, u, d+1);
}
}
}
void paint(int u, int p, vector<edge> &v){
used[u] = true;
for(int to : G[u]){
if(to == p) continue;
if(!used[to]){
paint(to, u, v);
col[u] += col[to];
if(col[to] == 0){
v.push_back((edge){u, to});
}
}
}
}
void clear(){
for(int i = 0; i < N; i++){
used[i] = false;
}
}
};
struct UnionFind {
vector<int> data;
UnionFind(int size) : data(size, -1) {}
bool unionSet(int x, int y) {
x = root(x); y = root(y);
if (x != y) {
if (data[y] < data[x]) swap(x, y);
data[x] += data[y]; data[y] = x;
}
return x != y;
}
bool findSet(int x, int y) {
return root(x) == root(y);
}
int root(int x) {
return data[x] < 0 ? x : data[x] = root(data[x]);
}
int size(int x) {
return -data[root(x)];
}
};
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout << setprecision(10) << fixed;
int n, m, q; cin >> n >> m >> q;
vector<edge> edges;
UnionFind uf(n+1);
for(int i = 0; i < m; i++){
int u, v; cin >> u >> v;
uf.unionSet(u, v);
edges.push_back(edge(u, v));
}
for(int i = 1; i <= n; i++){
if(uf.root(i) == i) {
edges.push_back(edge(0, i));
}
}
auto bridges = TwoEdgeConnectedComponents(edges, n+1).run();
UnionFind ok(n+1);
for(edge e: bridges){
if(e.from == 0 || e.to == 0) continue;
ok.unionSet(e.from, e.to);
}
while(q--){
int x, y; cin >> x >> y;
if(ok.findSet(x, y)) cout << "Yes" << endl;
else cout << "No" << endl;
}
}
milanis48663220