結果
| 問題 |
No.1420 国勢調査 (Easy)
|
| コンテスト | |
| ユーザー |
logx
|
| 提出日時 | 2021-01-29 20:53:27 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 44 ms / 2,000 ms |
| コード長 | 2,182 bytes |
| コンパイル時間 | 2,108 ms |
| コンパイル使用メモリ | 198,228 KB |
| 最終ジャッジ日時 | 2025-01-18 08:43:11 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 30 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
const char newl='\n';
//Tには可換群が載る.
template<typename T,T (*op)(T,T),T (*op_inv)(T,T)>
struct weight_uf{
int n;
vector<int> par;
vector<T> diff;
weight_uf(const int _):n(_),par(_,-1),diff(_,T(0)){}
//O(α(N))
int find(const int x){
if(par[x]<0)return x;
int r=find(par[x]);//根 この時に先祖のdiffの値も更新がかかる
diff[x]=op(diff[x],diff[par[x]]);
return par[x]=r;
}
//O(α(N))
T weight(const int x){
find(x);
return diff[x];
}
//!same(x,y)なる(x,y)に対しては動かない.
//O(α(N))
T diff_query(int x,int y){
return op_inv(weight(y),weight(x));
}
bool same(int x,int y){
return find(x)==find(y);
}
/*
既にある情報と矛盾する場合はreturn falseする.
diff[y]-diff[x]=wとなるようにunite.
*/
//O(α(N))
bool unite(int x,int y,T w){
if(same(x,y)){
//矛盾する
if(diff_query(x,y)!=w)return false;
//矛盾しない
else return true;
}
w=op(w,op_inv(weight(x),weight(y)));
x=find(x);
y=find(y);
if(par[x]>par[y])swap(x,y),w=op_inv(T(0),w);
int t=par[y]+par[x];
par[x]=t;
par[y]=x;
diff[y]=w;
n--;
return true;
}
//O(1)
int getsize(int i){
i=find(i);
return -par[i];
}
};
int op(int a,int b){
return a^b;
}
int op_inv(int a,int b){
return a^b;
}
int main(){
ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n,m;cin >> n >> m;
weight_uf<int,op,op_inv> uf(n);
bool ok=true;
while(m--){
int a,b;cin >> a >> b;
int y;cin >> y;
ok&=uf.unite(a-1,b-1,y);
}
if(!ok){
cout << -1 << newl;
return 0;
}
vector<int> ans(n);
rep(i,n){
if(uf.find(i)==i)ans[i]=0;
}
rep(i,n){
int r=uf.find(i);
ans[i]=ans[r]^uf.diff_query(i,r);
}
for(auto &e:ans)cout << e << newl;
}
logx