CodeForces 1240F Football

洛谷传送门

CF 传送门

挺妙的。

接下来我们将构造一个每条边都染色的方案,所以原来的 \(w_i\) 没用。

极差 \(\le 2\) 这个条件比较谔谔。考虑拆点,把原图变成二分图,那么 \(u, u + n\) 的极差只要都 \(\le 1\),原图就满足条件。

但是现在还不是很好做。考虑继续拆点。一个点 \(u\) 拆成 \(\left\lceil\frac{deg_u}{k}\right\rceil\) 个点,要求每个点的出边颜色互不相同。

现在就好做了。考虑对于每条边,先找到一个两端没使用过的颜色。如果存在那么直接染色。否则设 \(u\) 没使用过 \(c_1\)\(v\) 没使用过 \(c_2\),先强制把这条边染成 \(c_1\),然后递归找 \(v\) 的颜色为 \(c_1\) 的出边修改成 \(c_2\) 即可。

若成环,因为都是偶环,所以若到 \(u\) 相当于把 \(u\) 的使用过的 \(c_1\) 颜色的出边修改成 \(c_2\),不符合原有条件。

时间复杂度 \(O(nm^2)\),因为每次最坏情况会遍历整张图。但是实际跑得挺快的。

code
// Problem: F. Football
// Contest: Codeforces - Codeforces Round 591 (Div. 1, based on Technocup 2020 Elimination Round 1)
// URL: https://codeforces.com/problemset/problem/1240/F
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<int, int> pii;

const int maxn = 2010;

int n, m, K, deg[maxn], id[maxn], nt, a[maxn];
pii e[maxn][maxn];

void dfs(int u, int c1, int c2) {
	swap(e[u][c1], e[u][c2]);
	if (e[u][c2].fst) {
		a[e[u][c2].scd] = c2;
		dfs(e[u][c2].fst, c2, c1);
		e[e[u][c2].fst][c2] = mkp(u, e[u][c2].scd);
	}
}

void solve() {
	scanf("%d%d%d", &n, &m, &K);
	for (int i = 1; i <= n; ++i) {
		scanf("%*d");
	}
	for (int i = 1, u, v; i <= m; ++i) {
		scanf("%d%d", &u, &v);
		v += n;
		if (deg[u] % K == 0) {
			id[u] = ++nt;
		}
		if (deg[v] % K == 0) {
			id[v] = ++nt;
		}
		++deg[u];
		++deg[v];
		u = id[u];
		v = id[v];
		bool fl = 0;
		for (int j = 1; j <= K; ++j) {
			if (!e[u][j].fst && !e[v][j].fst) {
				e[u][j] = mkp(v, i);
				e[v][j] = mkp(u, i);
				a[i] = j;
				fl = 1;
				break;
			}
		}
		if (fl) {
			continue;
		}
		int c1 = 0, c2 = 0;
		for (int j = 1; j <= K; ++j) {
			if (!c1 && !e[u][j].fst) {
				c1 = j;
			}
			if (!c2 && !e[v][j].fst) {
				c2 = j;
			}
		}
		dfs(v, c1, c2);
		e[u][c1] = mkp(v, i);
		e[v][c1] = mkp(u, i);
		a[i] = c1;
	}
	for (int i = 1; i <= m; ++i) {
		printf("%d\n", a[i]);
	}
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

posted @ 2024-01-18 15:07  zltzlt  阅读(18)  评论(0)    收藏  举报