QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#98671#6329. Colorful GraphCSU2023TL 0ms0kbC++144.7kb2023-04-19 20:02:302023-04-19 20:02:34

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-04-19 20:02:34]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2023-04-19 20:02:30]
  • 提交

answer

#include <bits/stdc++.h>

template <class T>
inline void read(T &res)
{
	char ch; bool flag = false; res = 0;
	while (ch = getchar(), !isdigit(ch) && ch != '-');
	ch == '-' ? flag = true : res = ch ^ 48;
	while (ch = getchar(), isdigit(ch))
		res = res * 10 + ch - 48;
	flag ? res = -res : 0;
}

template <class T>
inline void nonnegative_put(T x)
{
	if (x > 9)
		nonnegative_put(x / 10);
	putchar(x % 10 + 48);
}

template <class T>
inline void put(T x)
{
	if (x < 0)
		x = -x, putchar('-');
	nonnegative_put(x);
}

template <class T>
inline void CkMin(T &x, T y) {x > y ? x = y : 0;}
template <class T>
inline void CkMax(T &x, T y) {x < y ? x = y : 0;}
template <class T>
inline T Min(T x, T y) {return x < y ? x : y;}
template <class T>
inline T Max(T x, T y) {return x > y ? x : y;}
template <class T>
inline T Abs(T x) {return x < 0 ? -x : x;}
template <class T>
inline T Sqr(T x) {return x * x;} 
//call Sqr((ll)x) when the type of returned value is "long long".

using std::map;
using std::set;
using std::pair;
using std::bitset;
using std::string;
using std::vector;
using std::complex;
using std::multiset;
using std::priority_queue;

typedef long long ll;
typedef long double ld;
typedef complex<ld> com;
typedef pair<int, int> pir;
const ld pi = acos(-1.0);
const ld eps = 1e-8;
const int Maxn = 1e9;
const int Minn = -1e9;
const int mod = 998244353; 
const int N = 14e3 + 5;

vector<int> e[N], re[N];
int sre[N], ans[N], ind[N], dfn[N], low[N], stk[N], col[N]; 
bool ins[N];
bitset<N> vis[N];
int T_data, n, m, C, top, tis;

const int M = 7e4 + 5;
int nxt[M], to[M], cap[M], adj[N], que[N], cur[N], lev[N];
int src, des, qr, T = 1;

inline void linkArc(int x, int y, int w)
{
	nxt[++T] = adj[x]; adj[x] = T; to[T] = y; cap[T] = w;
	nxt[++T] = adj[y]; adj[y] = T; to[T] = x; cap[T] = 0;	
}

inline bool Bfs()
{
	for (int x = 1; x <= des; ++x)	
		cur[x] = adj[x], lev[x] = -1;
	// 初始化具体的范围视建图而定,这里点的范围为 [1,n]
	que[qr = 1] = src;
	lev[src] = 0;
	for (int i = 1; i <= qr; ++i)
	{
		int x = que[i], y;
		for (int e = adj[x]; e; e = nxt[e])
			if (cap[e] > 0 && lev[y = to[e]] == -1)
			{
				lev[y] = lev[x] + 1;
				que[++qr] = y;
				if (y == des)
					return true;
			}
	}
	return false;
} 

inline int Dinic(int x, int flow)
{
	if (x == des)
		return flow;
	int y, delta, res = 0;	
	for (int &e = cur[x]; e; e = nxt[e]) 
		if (cap[e] > 0 && lev[y = to[e]] > lev[x])
		{
			delta = Dinic(y, Min(flow - res, cap[e]));
			if (delta)
			{
				cap[e] -= delta;
				cap[e ^ 1] += delta;
				res += delta;
				if (res == flow)
					break ; 
				//此时 break 保证下次 cur[x] 仍有机会增广 
			}
		} 
	if (res != flow)
		lev[x] = -1;
	return res; 
}

inline int maxFlow()
{
	int res = 0;
	while (Bfs())
		res += Dinic(src, Maxn);
	return res;
}

inline void Tarjan(int x)
{
	dfn[x] = low[x] = ++tis;
	stk[++top] = x;
	ins[x] = true; 
	for (int y : e[x])
		if (!dfn[y])
		{
			Tarjan(y);
			CkMin(low[x], low[y]);
		}
		else if (ins[y])
			CkMin(low[x], dfn[y]);
	if (dfn[x] == low[x])
	{
		int y;
		++C;
		do
		{
			y = stk[top--];
			ins[y] = false;
			col[y] = C;
		}while (y != x);
	}
}

inline void dfs(int x)
{
	ans[x] = tis;
	for (int y : re[x])
		if (ind[y])
		{
			--ind[y];
			dfs(y);
			return ;
		}			
}

int main()
{
	read(n); read(m);
	for (int i = 1, x, y; i <= m; ++i)
	{
		read(x); read(y);
		e[x].emplace_back(y);
	}
	for (int i = 1; i <= n; ++i)
		if (!dfn[i])
			Tarjan(i);
	for (int x = 1; x <= n; ++x)
	{
		for (int y : e[x])
			if (col[x] != col[y])
				vis[col[x]][col[y]] = 1;
		e[x].clear();
	}
	src = (C << 1) | 1, des = src + 1;
	for (int x = 1; x <= C; ++x)
	{
		linkArc(src, x, 1);
		linkArc(x + C, des, 1);
		linkArc(x + C, x, Maxn);
		for (int y = 1; y <= C; ++y)
			if (vis[x][y])
				linkArc(x, y + C, Maxn);
	}
	int _ans = maxFlow();
	for (int x = 1; x <= C; ++x)
		for (int e = adj[x]; e; e = nxt[e])
			if (!(e & 1) && to[e] > C && to[e] < src && to[e] - C != x && cap[e ^ 1] > 0)
			{
				for (int t = 1; t <= cap[e ^ 1]; ++t)
					re[x].emplace_back(to[e] - C);
				ind[to[e] - C] += cap[e ^ 1];
			}
	tis = 0;
	for (int x = 1; x <= C; ++x)
		sre[x] = re[x].size();
	for (int t = 1; t <= C; ++t)
	{
		for (int x = 1; x <= C; ++x)
			while (sre[x] > ind[x])
			{
				++tis;
				int u = x;
				ans[u] = tis;
				while (sre[u])
				{
					int v = re[u][sre[u]];
					re[u].pop_back();
					u = v;
					ans[v] = tis;
					--ind[v];
				}
			}
	}
	for (int x = 1; x <= C; ++x)
		if (!ans[x])
			ans[x] = ++tis;
	for (int i = 1; i <= n; ++i)
		put(ans[col[i]]), putchar(' ');
	putchar('\n');
}

詳細信息

Test #1:

score: 0
Time Limit Exceeded

input:

5 5
1 4
2 3
1 3
2 5
5 1

output:


result: