【JZOJ6206】【20190610】二分图边染色
题目
对一个二分图的边染色,满足有相同端点的边的颜色一定不同;
设最优染色为\(C\) ,你的染色为\(X\),只需要满足$ X \le 2^ {\lceil log \ C \rceil }$
\(n_1,n_2 \le 10^6 \ , \ m \le 5 \times 10^5\)
题解
这题由于没有很好地分析条件,只写了一个\(n m \sqrt m\) 的二分图匹配暴力
首先答案应该是\(max \ deg_i\)
证明:
显然\(C \ge deg_m\)
设二分图的两部为\(X\)和\(Y\),\(deg_m = max \ deg_i\)
考虑选出\(X\)部的\(deg_i = deg_m\)的点,在\(Y\)部去找到一个完备匹配:
利用霍尔定理,如果不满足,一定存在\(X\)选了\(x\)个\(deg_i = deg_m\) 的点,但是在\(Y\)和它们连通的点只有\(y\)个\((y \lt x)\),根据鸽巢原理,这\(y\)个点之中一定存在有\(deg_j \ge \lceil \frac{x \times deg_m}{y}\rceil \gt deg_m\) ,矛盾所以只考虑\(deg_m\)的点,\(X\)一定有一个完配\(M_x\),\(Y\)一定有一个完配\(M_y\)
考虑$M_x \cup M_y $ 形成的若干个连通块,由于所有点的度数<=2,那么一个连通块只能是:
$M_x \cap M_y $ 的一条边
环 (每个点都满足\(deg_i =deg_m\))
一条简单路径(只有末尾的某个端点不满足\(deg \neq deg_m\))
后两者显然都可以调整到满足所有的\(deg_i=deg_m\)的点都被选入匹配
所以一次匹配\(deg_m\)至少-1,重复这样的匹配,即\(C \le deg_m\) ,证毕
题意启示我们去二分,可以补出两个虚点使得左右的度数都为偶数
做欧拉回路对边染不同的色就可以每次使得\(deg_m\)折半
#include<bits/stdc++.h> using namespace std; const int N=2000010;
int n1,n2,n,m,hd[N],o,now,d[N],vis[N],col[N],C;
struct edge{int u,v,w;}e[N]; char gc(){
static char*p1,*p2,s[1000000];
if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);
return(p1==p2)?EOF:*p1++;
}
int rd(){
int x=0;char c=gc();
while(c<'0'||c>'9')c=gc();
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc();
return x;
} struct Edge{int v,nt,w;}E[N<<1];
void adde(int u,int v,int w){
vis[w]=0;
E[o]=(Edge){v,hd[u],w};hd[u]=o++;
E[o]=(Edge){u,hd[v],w};hd[v]=o++;
d[u]++;d[v]++;
} void dfs(int u){
for(int&i=hd[u];i;i=E[i].nt){
if(vis[E[i].w])continue;
int tmp=E[i].w;
vis[tmp]=1;
dfs(E[i].v);
now^=1;vis[tmp]=now;
}
} void solve(int l,int r){
o=1;for(int i=l;i<=r;++i)adde(e[i].u,e[i].v,i);
int fg=0,cnt=m;
d[n+1]=d[n+2]=0;
for(int i=l;i<=r;++i){
int u=e[i].u,v=e[i].v;
if(d[u]>1||d[v]>1)fg=1;
if(d[u]&1)adde(u,n+1,++cnt);
if(d[v]&1)adde(v,n+2,++cnt);
d[u]=d[v]=0;
}
if(d[n+1]&1)adde(n+1,n+2,++cnt);
d[n+1]=d[n+2]=0;
if(!fg){
++C;hd[n+1]=hd[n+2]=0;
for(int i=l;i<=r;++i){
col[e[i].w]=C;
hd[e[i].u]=hd[e[i].v]=0;
}
return ;
}
now=2;
for(int i=l;i<=r;++i)if(!vis[i]){
dfs(e[i].u);
} static edge tmp[N];int p1=l,p2=0,mid;
for(int i=l;i<=r;++i)if(vis[i]&1)e[p1++]=e[i];else tmp[++p2]=e[i];
mid=p1;for(int i=1;i<=p2;++i)e[p1++]=tmp[i]; solve(l,mid-1);
solve(mid,r);
} int main(){
freopen("color.in","r",stdin);
freopen("color.out","w",stdout);
n1=rd();n2=rd();m=rd();
for(int i=1;i<=m;++i){
int u=rd(),v=rd();
e[i]=(edge){u,v+n1,i};
}
n=n1+n2;
solve(1,m);
printf("%d\n",C);
for(int i=1;i<=m;++i)printf("%d\n",col[i]);
return 0;
}
【JZOJ6206】【20190610】二分图边染色的更多相关文章
- 二分图点染色 BestCoder 1st Anniversary($) 1004 Bipartite Graph
题目传送门 /* 二分图点染色:这题就是将点分成两个集合就可以了,点染色用dfs做, 剩下的点放到点少的集合里去 官方解答:首先二分图可以分成两类点X和Y, 完全二分图的边数就是|X|*|Y|.我们的 ...
- hdu 5285 二分图黑白染色
题意:给出 n 个人,以及 m 对互不认识的关系,剩余的人都互相认识,要将所有人分成两组,组内不能有互不认识的人,要求每组至少有一人,并且第一组人数尽量多,问两组人数或不可能时单独输出 BC 48 场 ...
- UVA - 10004 Bicoloring(判断二分图——交叉染色法 / 带权并查集)
d.给定一个图,判断是不是二分图. s.可以交叉染色,就是二分图:否则,不是. 另外,此题中的图是强连通图,即任意两点可达,从而dfs方法从一个点出发就能遍历整个图了. 如果不能保证从一个点出发可以遍 ...
- 2019 ACM/ICPC Asia Regional shanxia D Miku and Generals (二分图黑白染色+01背包)
Miku is matchless in the world!” As everyone knows, Nakano Miku is interested in Japanese generals, ...
- cf 557D 二分图黑白染色
题意:给出一个 n 点 m 边的图,问最少加多少边使其能够存在奇环,加最少边的情况数有多少种 奇环和偶环其实就是二分图的性质:二分图不存在奇环,所以只要判断这张图是否是二分图就行了: 如果本身就不是二 ...
- cojs 二分图计数问题1-3 题解报告
OwO 良心的FFT练手题,包含了所有的多项式基本运算呢 其中一部分解法参考了myy的uoj的blog 二分图计数 1: 实际是求所有图的二分图染色方案和 我们不妨枚举这个图中有多少个黑点 在n个点中 ...
- 3 Steps(二分图)
C - 3 Steps Time limit : 2sec / Memory limit : 256MB Score : 500 points Problem Statement Rng has a ...
- 虚拟化构建二分图(BZOJ2080 题解+浅谈几道双栈排序思想的题)
虚拟化构建二分图 ------BZOJ2080 题解+浅谈几道双栈排序思想的题 本题的题解在最下面↓↓↓ 不得不说,第一次接触类似于双栈排序的这种题,是在BZOJ的五月月赛上. [BZOJ4881][ ...
- [POJ2942]Knights of the Round Table(点双+二分图判定——染色法)
建补图,是两个不仇恨的骑士连边,如果有环,则可以凑成一桌和谐的打麻将 不能直接缩点,因为直接缩点求的是连通分量,点双缩点只是把环缩起来 普通缩点 ...
随机推荐
- 阿里云负载均衡SLB上用免费的Let's Encrypt的SSL证书
Let's Encrypt是很火的一个免费SSL证书发行项目,自动化发行证书,证书有90天的有效期.Let's Encrypt已经发布了工具certbot,用此工具生成证书.证书续期非常简单. 以下是 ...
- [HNOI2012]矿场搭建 (点双连通)
题目 [HNOI2012]矿场搭建 解析 这个题做的我十分自闭.. 没看出这个是个点双,然后一晚上+半上午.. 一看肯定和割点有关,我们找到所有的点双,会发现有这么几种情况 连通块中一个割点也没有,这 ...
- 2019-07-25 php错误级别及设置方法
在php的开发过程里,我们总是会有一系列的错误警告,这些错误警告在我们开发的过程中是十分需要的,因为它能够提示我们在哪里出现了错误,以便修改和维护.但在网站开发结束投入使用时,这些报错我们就要尽量避免 ...
- Commander基本使用
随着NodeJs的不断发展,对于前端来说要做的东西也就更多,Vue脚手架React脚手架等等等一系列的东西都脱颖而出,进入到人们的视野当中,对于这些脚手架工具来讲也只是停留在应用阶段,从来没有想过脚手 ...
- js事件(十二)
一.事件三要素1.事件目标[谁触发的该事件(引起该事件触发的源头:target)]2.事件处理程序[处理相应事件的函数]3.事件对象[触发事件产生的携带事件信息的对象] 二.事件流[从页面中接受事件的 ...
- honeyd使用
honeyd可以同时模仿上千个不同的计算机 官网 honeyd-1.5c.tar.gz:http://www.honeyd.org 依赖包 libevent-1.3a.tar.gz:http://li ...
- 升级tinyhttpd-0.1.0,让其支持网页显示图像
tinyhttpd是学习http协议非常好的工具,但是由于其过于简单,不支持在网页上显示图片,所以我改了一些代码,让tinyhttpd可以现实图像,供新手一起学习和熟悉http协议,ubuntu14. ...
- Swagger Liunx环境搭建(亲测百分百可用)
一.安装nodejs 下载编译好的nodejs安装包,下载地址: https://nodejs.org/dist/v10.10.0/ (作者下载的10.10.0,可根据自己需要下载不同版本) 将下载好 ...
- 爬取网易云音乐歌手和id
pip install lxml csv requests from lxml import etree from time import sleep import csv import reques ...
- Gitlab创建一个项目(二)创建新用户以及分配项目
Gitlab创建一个项目(一) 1.进入gitlab控制台 2.点击“新建用户” 3.点击“Edit”,创建初始密码 4.分配项目,首页进入项目 5.进入Members菜单 6.选择用户 7.赋予权限 ...