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;
}

  


CodeForces - 600F Edge coloring of bipartite graph的更多相关文章

  1. Edge coloring of bipartite graph CodeForces - 600F (二分图染色)

    大意:给定二分图, 求将边染色, 使得任意邻接边不同色且使用颜色种类数最少 最少颜色数即为最大度数, 要输出方案的话, 对于每一条边(u,v), 求出u,v能使用的最小的颜色$t0$,$t1$ 若t0 ...

  2. Educational Codeforces Round 2 Edge coloring of bipartite graph

    题意: 输入一个二分图,用最少的颜色数给它的每条边染色,使得同一个顶点连的边中颜色互不相同. 输出至少需要的颜色数和任意一种染色方案. 分析: 证明不会,只说一下(偷瞄巨巨代码学到的)做法. 假设点的 ...

  3. hdu 5313 Bipartite Graph(dfs染色 或者 并查集)

    Problem Description Soda has a bipartite graph with n vertices and m undirected edges. Now he wants ...

  4. HDU 5313——Bipartite Graph——————【二分图+dp+bitset优化】

    Bipartite Graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  5. HDU 5313 Bipartite Graph(二分图染色+01背包水过)

    Problem Description Soda has a bipartite graph with n vertices and m undirected edges. Now he wants ...

  6. 二分图点染色 BestCoder 1st Anniversary($) 1004 Bipartite Graph

    题目传送门 /* 二分图点染色:这题就是将点分成两个集合就可以了,点染色用dfs做, 剩下的点放到点少的集合里去 官方解答:首先二分图可以分成两类点X和Y, 完全二分图的边数就是|X|*|Y|.我们的 ...

  7. Learning Query and Document Similarities from Click-through Bipartite Graph with Metadata

    读了一篇paper,MSRA的Wei Wu的一篇<Learning Query and Document Similarities from Click-through Bipartite Gr ...

  8. Codeforces 1027E Inverse Coloring 【DP】

    Codeforces 1027E Inverse Coloring 题目链接 #include<bits/stdc++.h> using namespace std; #define N ...

  9. CodeForces 505B Mr. Kitayuta's Colorful Graph

    Mr. Kitayuta's Colorful Graph Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d ...

随机推荐

  1. python 面对对象基础

    目录 面向对象基础 面向对象编程(抽象) 类与对象 给对象定制独有的特征 对象的属性查找顺序 类与对象的绑定方法 类与数据类型 对象的高度整合 面向对象基础 面向对象编程(抽象) 回顾一下 面向过程编 ...

  2. UVA - 11572 Unique Snowflakes 滑动扫描

    题目:点击打开题目链接 思路:从左往右扫描,定义扫描左端点L,右端点R,保证每次往几何中添加的都是符合要求的连续的数列中的元素,L和R从0扫到n,复杂度为O(n),使用set维护子数列,set查找删除 ...

  3. Linux编程中链接库的使用

    链接库本质上是一段可执行的二进制代码,可以被操作系统载入内存执行.按加载的时机不同,链接库可以分为静态链接库和动态链接库. 静态链接库:编译过程中加载进可执行文件的库(静态库省去了运行时加载的消耗,但 ...

  4. 迷宫问题&MakeFile

    先看一个有意思的问题, 我们定义一个二维数组表示迷宫. 它表示一个迷宫, 其中的1表示墙壁,0表示可以走的路, 只能横着走或竖着走,不能斜着走, 我们要编程序找出从左上角到右下角的路线.其实这个问题可 ...

  5. 枚举进程——暴力搜索内存(Ring0)

    上面说过了隐藏进程,这篇博客我们就简单描述一下暴力搜索进程. 一个进程要运行,必然会加载到内存中,断链隐藏进程只是把EPROCESS从链表上摘除了,但它还是驻留在内存中的.这样我们就有了找到它的方法. ...

  6. linux内核代码注释 赵炯 第三章引导启动程序

    linux内核代码注释 第三章引导启动程序 boot目录中的三个汇编代码文件   bootsect.s和setup.s采用近似intel的汇编语法,需要8086汇编器连接器as86和ld86 head ...

  7. csa Round #66 (Div. 2 only)

    csa66 Risk Rolls Time limit: 1000 msMemory limit: 256 MB   Alena and Boris are playing Risk today. W ...

  8. Goal Oriented Action Planning for a Smarter AI

    Goal Oriented Action Planning for a Smarter AI by Brent Owens23 Apr 2014 Goal Oriented Action Planni ...

  9. HashSet源码分析 jdk1.6

    Set的特点:Set元素无顺序,且元素不可以重复. 1.定义 public class HashSet<E> extends AbstractSet<E> implements ...

  10. 【Luogu】P3332K大数查询(树套树)

    题目链接 这题我费尽心思不用标记永久化终于卡过去了qwq 权值线段树下面套一个区间线段树.然后乱搞搞即可. // luogu-judger-enable-o2 #include<cstdio&g ...