CF600F Edge coloring of bipartite graph 题解
结论是颜色数为最大的点的度数。
必要性是显然的。
对于充分性,考虑构造一种方案。
坚持一个原则,尽量用没用过的颜色里面编号最小的。
每次加边
如果
否则我们把边设为其中的任意一个颜色,假设你设为
这样一直更新就行了。
显然,我们是以
因为二分图有环长度必然是偶数,所以我们染的是
那为啥是最大的点的度数呢?
我们考虑每次相当于
时间复杂度为
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const LL N=2005;
const LL M=2e5+5;
LL A,B,m,ans,c[N][N],du[N],u[M],v[M];
int main()
{
scanf("%lld%lld%lld",&A,&B,&m);
for(int i=1;i<=m;i++)
{
scanf("%lld%lld",&u[i],&v[i]);
v[i]+=A;
du[u[i]]++,du[v[i]]++;
}
LL ans=0;
for(int i=1;i<=A+B;i++)ans=max(ans,du[i]);
printf("%lld\n",ans);
for(int i=1;i<=m;i++)
{
LL mx1=1,mx2=1;
while(c[u[i]][mx1])++mx1;
while(c[v[i]][mx2])++mx2;
c[u[i]][mx1]=v[i],c[v[i]][mx2]=u[i];
if(mx1==mx2)continue;
for(LL t=mx2,x=v[i];x;x=c[x][t],t^=mx1^mx2)swap(c[x][mx1],c[x][mx2]);
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=ans;j++)
{
if(c[u[i]][j]==v[i])
{
printf("%d ",j);
break;
}
}
}
}