二分图边染色,2-approximate。
(L,Rle10^5,Mle5cdot10^5)。
边染色都做过两道题了咋还不会做啊。
把 2-Coloring 那题拿过来,两种颜色分治一下,没了。
复杂度 (O(Mlog M))。
#include<bits/stdc++.h>
#define PB emplace_back
#define fi first
#define se second
#define MP make_pair
using namespace std;
typedef pair<int, bool> pib;
const int N = 500003;
template<typename T>
void rd(T &x){
int ch = getchar(); x = 0;
for(;ch < '0' || ch > '9';ch = getchar());
for(;ch >= '0' && ch <= '9';ch = getchar()) x = x * 10 + ch - '0';
}
int n1, n2, m, ccnt, ans[N], fa[N], siz[N], mat[N];
bool val[N];
struct Node {int u, v, id;};
pib getf(int x){
if(fa[x] == x) return MP(x, false);
pib tp = getf(fa[x]);
return MP(fa[x] = tp.fi, val[x] ^= tp.se);
}
void comb(int u, int v){
pib p1 = getf(u), p2 = getf(v);
if(p1.fi == p2.fi) return;
if(siz[p1.fi] > siz[p2.fi]) swap(p1, p2);
siz[p2.fi] += siz[p1.fi]; fa[p1.fi] = p2.fi;
val[p1.fi] = (p1.se == p2.se);
}
void work(const vector<Node> &E){
int m = E.size(); bool flg = false;
for(const Node &e : E) mat[e.u] = mat[e.v] = -1;
for(int i = 0;i < m;++ i){
fa[i] = i; siz[i] = 1;
val[i] = false;
}
for(int i = 0;i < m;++ i){
int u = E[i].u, v = E[i].v;
if(~mat[u]){
flg = true;
comb(mat[u], i);
mat[u] = -1;
} else mat[u] = i;
if(~mat[v]){
flg = true;
comb(mat[v], i);
mat[v] = -1;
} else mat[v] = i;
}
if(!flg){
++ccnt;
for(const Node &e : E)
ans[e.id] = ccnt;
return;
}
vector<Node> E1, E2;
for(int i = 0;i < m;++ i)
(getf(i).se ? E2 : E1).PB(E[i]);
work(E1); work(E2);
}
int main(){
rd(n1); rd(n2); rd(m);
vector<Node> E(m);
for(int i = 0;i < m;++ i){
rd(E[i].u); rd(E[i].v);
E[i].v += n1; E[i].id = i;
} work(E); printf("%d
", ccnt);
for(int i = 0;i < m;++ i) printf("%d
", ans[i]);
}