QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#426418 | #6329. Colorful Graph | EXODUS | RE | 0ms | 0kb | C++17 | 5.1kb | 2024-05-31 10:32:40 | 2024-05-31 10:32:40 |
answer
#include <vector>
#include <algorithm>
#include <cassert>
namespace exodus{
namespace internal{
class nothing{
public:
nothing(){}
friend nothing operator +(const nothing&,const nothing&){return nothing();}
};
}
template<class info=internal::nothing>
struct dsu{
public:
struct node{
public:
node(){anc=-1,siz=1,ifo=info();}
int anc,siz;
info ifo;
};
dsu():_n(0){}
explicit dsu(int n){
_n=n;node.resize(n);
for(int i=0;i<n;i++)
node[i].anc=i;
}
void build(int n){
_n=n;
node.clear();
node.resize(n);
for(int i=0;i<n;i++)
node[i].anc=i;
}
int find(int u){
assert(0<=u&&u<_n);
return __find(u);
}
void merge(int u,int v){
assert(0<=u&&u<_n);
assert(0<=v&&v<_n);
u=__find(u),v=__find(v);
if(node[u].siz<node[v].siz)std::swap(u,v);
node[v].anc=u;
node[u].ifo=node[u].ifo+node[v].ifo;
}
bool check(int u,int v){
assert(0<=u&&u<_n);
assert(0<=v&&v<_n);
u=__find(u),v=__find(v);
return u==v;
}
private:
int _n;
std::vector<node>node;
int __find(int u){
return u==node[u].anc?u:node[u].anc=__find(node[u].anc);
}
};
}
#include <algorithm>
#include <array>
#include <cassert>
#include <functional>
#include <numeric>
#include <queue>
#include <tuple>
#include <vector>
#include <iostream>
namespace exodus{
struct scc_graph{
public:
scc_graph(){n=0;}
explicit scc_graph(int _n){n=_n;g.resize(n);}
std::vector<std::pair<int,int>>edges(){return edge;}
std::pair<int,int>get_edge(int i){
assert(0<=i&&i<(int)edge.size());
return edge[i];
}
void add_edge(int u,int v){
assert(0<=u&&u<n);
assert(0<=v&&v<n);
g[u].emplace_back(v);
edge.emplace_back(u,v);
}
std::vector<std::vector<int>> scc(){
std::vector<int>dfn(n,0),low(n,0),stk,ins(n,0),col(n,-1);
int dfx=0,col_cnt=0;
stk.reserve(n);
std::function<void(int)>tarjan=[&](int u){
dfn[u]=low[u]=++dfx;ins[u]=true;stk.emplace_back(u);
for(auto v:g[u])
if(!dfn[v])tarjan(v),low[u]=std::min(low[u],low[v]);
else if(ins[v])low[u]=std::min(low[u],dfn[v]);
if(dfn[u]==low[u]){
while(u!=stk.back())col[stk.back()]=col_cnt,ins[stk.back()]=false,stk.pop_back();
col[stk.back()]=col_cnt,ins[stk.back()]=false,stk.pop_back();
++col_cnt;
}
};
for(int i=0;i<n;i++)
if(!dfn[i])
tarjan(i);
std::vector<std::vector<int>>res(col_cnt);
for(int i=0;i<n;i++)
res[col[i]].emplace_back(i);
return res;
}
private:
int n;
std::vector<std::vector<int>>g;
std::vector<std::pair<int,int>>edge;
};
}
#include<bits/stdc++.h>
using namespace std;
bitset<7000>bts[7000],used;
vector<int>g[7000];
int main(){
freopen("color.in","r",stdin);
freopen("color.out","w",stdout);
cin.tie(nullptr)->sync_with_stdio(false);
int n,m;
cin>>n>>m;
vector<pair<int,int>>edge(m);
for(auto& [u,v]:edge)
cin>>u>>v,--u,--v;
for(auto [u,v]:edge){
g[u].emplace_back(v);
}
auto bfs=[&](int s){
static queue<int>q;
q.emplace(s);
bts[s][s]=true;
while(!q.empty()){
int u=q.front();
q.pop();
for(auto v:g[u]){
if(!bts[s][v]){
bts[s][v]=true;
q.emplace(v);
}
}
}
};
for(int i=0;i<n;i++)
bfs(i);
for(int i=0;i<n;i++){
bts[i].reset(i);
for(int j=i+1;j<n;j++){
if(bts[i].test(j)&&bts[j].test(i)){
bts[j].reset(i);
}
}
}
int cnt=n;
vector<int>match(n);
vector<int>nxt(n,-1);
auto dfs=[&](auto self,int u)-> bool {
auto caonima=bts[u]&used;
for(int v=caonima._Find_first();v<n;v=caonima._Find_next(v)){
used.set(v,false);
if(nxt[v]==-1||self(self,nxt[v])){
nxt[v]=u;
return true;
}
}
return false;
};
// mt19937 seed(chrono::steady_clock::now().time_since_epoch().count());
// shuffle(ord.begin(),ord.end(),seed);
for(int i=0;i<n;i++){
used.set();
if(dfs(dfs,i))
cnt--;
}
#ifdef EXODUS
cerr<<cnt<<'\n';
#endif
exodus::dsu dsu(n);
for(int u=0;u<n;u++){
if(nxt[u]!=-1){
dsu.merge(u,nxt[u]);
}
}
vector<int>ans(n);
for(int i=0;i<n;i++){
static int colx=0;
if(dsu.find(i)==i){
ans[i]=++colx;
}
}
for(int i=0;i<n;i++){
ans[i]=ans[dsu.find(i)];
}
for(int i=0;i<n;i++)
cout<<ans[i]<<' ';
cout<<'\n';
#ifdef EXODUS
cerr<<clock()<<'\n';
vector<vector<int>>_g(n);
vector<vector<int>>reach(n,vector<int>(n));
for(auto [u,v]:edge){
_g[u].emplace_back(v);
}
auto _bfs=[&](int s){
static queue<int>q;
q.emplace(s);
reach[s][s]=true;
while(!q.empty()){
int u=q.front();
q.pop();
for(auto v:_g[u]){
if(!reach[s][v]){
reach[s][v]=true;
q.emplace(v);
}
}
}
};
for(int i=0;i<n;i++)
_bfs(i);
// for(int i=0;i<n;i++,cerr<<'\n')
// for(int j=0;j<n;j++)
// cerr<<reach[i][j]<<' ';
vector<int>_lis;
for(int i=1;i<=cnt;i++){
_lis.clear();
for(int j=0;j<n;j++)
if(ans[j]==i)
_lis.emplace_back(j);
for(auto u:_lis)
for(auto v:_lis){
if(!reach[u][v]&&!reach[v][u]){
cerr<<"Wrong Answer\n";
return 1;
}
}
}
cerr<<"Accept\n";
#endif
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Dangerous Syscalls
input:
5 5 1 4 2 3 1 3 2 5 5 1