QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#426418#6329. Colorful GraphEXODUSRE 0ms0kbC++175.1kb2024-05-31 10:32:402024-05-31 10:32:40

Judging History

你现在查看的是最新测评结果

  • [2024-05-31 10:32:40]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [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

output:


result: