CodeForces 1240F Football
挺妙的。
接下来我们将构造一个每条边都染色的方案,所以原来的 \(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;
}

浙公网安备 33010602011771号