CodeForces - 600F Edge coloring of bipartite graph

Discription

You are given an undirected bipartite graph without multiple edges. You should paint the edges of graph to minimal number of colours, so that no two adjacent edges have the same colour.

Input

The first line contains three integers a, b, m (1 ≤ a, b ≤ 1000, 0 ≤ m ≤ 105), a is the size of the first part, b is the size of the second part, m is the number of edges in the graph.

Each of the next m lines contains two integers x, y (1 ≤ x ≤ a, 1 ≤ y ≤ b), where x is the number of the vertex in the first part and y is the number of the vertex in the second part. It is guaranteed that there are no multiple edges.

Output

In the first line print integer c — the minimal number of colours. The second line should contain m integers from 1 to c — the colours of the edges (in the order they appear in the input).

If there are several solutions, you can print any one of them.

Example

Input
4 3 5
1 2
2 2
3 2
4 1
4 3
Output
3
1 2 3 1 2


一种全新的题目类型:给二分图染色使得任意两个邻接的边颜色不同,求最少需要的颜色并输出任意一种方案。

如果仅仅需要输出最小颜色数的话,根据二分图没有奇环的性质是很容易yy,答案就是度数最大的点的度数,但是还要输出方案,,,这有点gg。
假设我们已经处理好了前i-1条边,现在要加入第i条边(左右连接的顶点分别是u,v,并且其没有出现过的颜色最小分别是C1,C2)。我们先把这条边染成c1色,
但是这样V顶点可能就有两个颜色c1的边了。如果v顶点原来还有一条颜色是c1的边的话,那么就把它染成c2色,再进入另一个端点继续递归。。

我们发现这种操作就是把(u,v)这条边加进原来一条 由颜色C1,C2交替出现的路径中去,其中v是原来的路径端点之一,如果(u,v)和原来v的边颜色冲突的话,
就把原来路径上的所有邻接边颜色互换一下,所以肯定有解。


现在我们唯一需要证明的是 这种策略可以使得 所有出现的边的最大颜色编号 就是 度数最大的点的度数。
考虑我们都是贪心的找需要加入的边的两个端点 没有出现过的最小颜色,所以假设出现了编号大于度数最大的点度数 的边,那么说明这条边的某个顶点的度数一定
大于度数最大的点的度数,但是这显然是矛盾的,所以不成立。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1005;
int G[maxn][maxn],C[maxn*100];
int A,B,m,dy[2][maxn][maxn],ans;
int u[maxn*100],v[maxn*100],c[2];

void dfs(int a,int b,int x,int y,int now,int pre){
	if(now==pre){ dy[a][x][now]=y,dy[b][y][now]=x; return;}
	
	int to=dy[b][y][now];
	dy[a][x][now]=y,dy[b][y][now]=x;
	
	if(!to) dy[b][y][pre]=0;
	else dfs(b,a,y,to,pre,now);
}

int main(){
	scanf("%d%d%d",&A,&B,&m);
	for(int i=1;i<=m;i++){
		scanf("%d%d",u+i,v+i);
		G[u[i]][v[i]]=i;
	}
	
	for(int i=1;i<=m;i++){
		c[0]=c[1]=1;
		while(dy[0][u[i]][c[0]]) c[0]++;
		while(dy[1][v[i]][c[1]]) c[1]++;
		ans=max(ans,max(c[0],c[1]));
		dfs(0,1,u[i],v[i],c[0],c[1]);
	}
	
	for(int i=1;i<=A;i++)
	    for(int j=1;j<=ans;j++) if(dy[0][i][j]) C[G[i][dy[0][i][j]]]=j;
	
	printf("%d\n",ans);
	for(int i=1;i<=m;i++) printf("%d ",C[i]);
	return 0;
}

  




猜你喜欢

转载自www.cnblogs.com/JYYHH/p/8915563.html