QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#132366#6329. Colorful GraphShuishuiWA 1ms7944kbC++143.9kb2023-07-29 18:01:302023-07-29 18:01:33

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-07-29 18:01:33]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:7944kb
  • [2023-07-29 18:01:30]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int N = 7e3 + 2;
const int V = 1e5, E = 1e5;
template<typename T>
struct MinGraph {
	int s, t, vtot;
	int head[V], etot;
	T dis[V], flow, cost, pf[V]; 
	int pre[V];
	bool vis[V];
	struct edge{
		int v, nxt;
		T f, c;
	} e[E * 2];

	void addedge(int u, int v, T f, T c, T f2 = 0)
	{
		e[etot] = {v, head[u], f, c}; head[u] = etot++;
		e[etot] = {u, head[v], f2, -c}; head[v] = etot++;
	}

	bool spfa()
	{	
		T inf = numeric_limits<T>::max() / 2;
		for (int i = 1; i <= vtot; i++)
		{
			dis[i] = inf;
			vis[i] = false;
			pre[i] = -1;
			pf[i] = inf;
		}

		dis[s] = 0;
		vis[s] = true;
		queue<int> q;
		q.push(s);
		while (!q.empty())
		{
			int u = q.front();;
			for (int i = head[u]; ~i; i = e[i].nxt)
			{
				int v = e[i].v;
				if (e[i].f && dis[v] > dis[u] + e[i].c)
				{
					dis[v] = dis[u] + e[i].c;
					pre[v] = i;
					pf[v] = min(pf[u], e[i].f);
					if (!vis[v]) 
					{
						vis[v] = 1;
						q.push(v);
					}
				}
			}
			q.pop();
			vis[u] = false;
		}
		return dis[t] != inf;
	}

	void augment()
	{
		int u = t;
		T f = pf[t];
		flow += f;
		cost += f * dis[t];
		while (~pre[u])
		{
			e[pre[u]].f -= f;
			e[pre[u]^1].f += f;
			u = e[pre[u]^1].v;
		}
	}

	pair<T, T> solve()
	{
		flow = 0;
		cost = 0;
		while (spfa()) augment();
		return {flow, cost};
	}

	void init(int s_, int t_, int vtot_)
	{
		s = s_, t = t_, vtot = vtot_;
		etot = 0;
		for (int i = 1; i <= vtot; i++) head[i] = -1;
	}
};

int dfn[N], low[N], bel[N], sz[N], tot, cnt;
bool ins[N];
stack<int> stk;
vector<int> scc[N];
vector<int> e[N];

void dfs(int x)
{
	dfn[x] = low[x] = ++tot;
	ins[x] = true;
	stk.push(x);
	for (auto y : e[x])
	{
		if (!dfn[y]) dfs(y);
		if (ins[y]) low[x] = min(low[x], low[y]);
	}

	if (dfn[x] == low[x])
	{
		vector<int> v;
		cnt++;
		while (true)
		{
			int y = stk.top();
			stk.pop();
			ins[y] = false;
			scc[cnt].push_back(y);
			bel[y] = cnt;
			sz[cnt]++;
			if (y == x) break;
		}
	}
}

MinGraph<ll> g;

void solve(void)
{
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= m; i++)
	{
		int u, v;
		cin >> u >> v;
		e[u].push_back(v);
	}

	for (int i = 1; i <= n; i++) if (!dfn[i]) dfs(i);
	
	// for (int i = 1; i <= n; i++)
	// 	cout << bel[i] << " ";
	// cout << "\n";
	// cout << cnt << "\n";
	int s = cnt * 2 + 1, t = cnt * 2 + 2;
	g.init(s, t, t);

	vector<array<int, 2>> used;

	for (int i = 1; i <= cnt; i++)
	{
		used.push_back({i, g.etot});
		g.addedge(s, i * 2 - 1, m, 1);
		g.addedge(i * 2 - 1, t, 1, 0);
		g.addedge(s, i * 2, 1, 0);
		g.addedge(i * 2 - 1, i * 2, 1, 0);

	}

	for (int x = 1; x <= n; x++)
	{
		int i = bel[x];

		for (auto y : e[x])
		{
			int u = bel[x], v = bel[y];
			if (u == v)
				continue; 
			// cout << u << " " << v << "\n";
			g.addedge(u * 2, v * 2 - 1, m, 0);
		}
	}

	vector<int> ans(n + 2);

	auto [f, c] = g.solve();
	// cout << c << "\n";



	vector<int> vis(n * 2 + 2);
	int now = 0;
	for (auto [uid, eid] : used)
	{
		if (g.e[eid].f != m)
		{
			// cout << "\n";
			// cout << uid << "\n";
			now++;
			vis[uid * 2] = true;

			for (auto v : scc[uid])
			{
				// cout << v << " ";
				ans[v] = now;
			}


			queue<int> q;
			q.push(uid * 2);
			while (!q.empty())
			{
				int u = q.front();
				// cout << u << "\n";
				for (int i = g.head[u]; ~i; i = g.e[i].nxt)
				{
					int v = g.e[i].v;
					if (v != t && g.e[i].f != m && !vis[v])
					{
						vis[v] = true;

						for (auto nd : scc[(v + 1) / 2])
							ans[nd] = now;
					
						q.push(v + 1);
					}
				}
				q.pop();
			}
		}
	}

	for (int i = 1; i <= n; i++)
		cout << ans[i] << " ";
	cout << "\n";
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	// int T;
	// cin >> T;
	// for (int i = 1; i <= T; i++)
		solve();

	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 1ms
memory: 7944kb

input:

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

output:

1 2 1 1 1 

result:

wrong answer 4 and 3 are not connected