题目

​ 对一个二分图的边染色,满足有相同端点的边的颜色一定不同;

​ 设最优染色为\(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,那么一个连通块只能是:

    1. $M_x \cap M_y $ 的一条边

    2. 环 (每个点都满足\(deg_i =deg_m\))

    3. 一条简单路径(只有末尾的某个端点不满足\(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】二分图边染色的更多相关文章

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

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

  2. hdu 5285 二分图黑白染色

    题意:给出 n 个人,以及 m 对互不认识的关系,剩余的人都互相认识,要将所有人分成两组,组内不能有互不认识的人,要求每组至少有一人,并且第一组人数尽量多,问两组人数或不可能时单独输出 BC 48 场 ...

  3. UVA - 10004 Bicoloring(判断二分图——交叉染色法 / 带权并查集)

    d.给定一个图,判断是不是二分图. s.可以交叉染色,就是二分图:否则,不是. 另外,此题中的图是强连通图,即任意两点可达,从而dfs方法从一个点出发就能遍历整个图了. 如果不能保证从一个点出发可以遍 ...

  4. 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, ...

  5. cf 557D 二分图黑白染色

    题意:给出一个 n 点 m 边的图,问最少加多少边使其能够存在奇环,加最少边的情况数有多少种 奇环和偶环其实就是二分图的性质:二分图不存在奇环,所以只要判断这张图是否是二分图就行了: 如果本身就不是二 ...

  6. cojs 二分图计数问题1-3 题解报告

    OwO 良心的FFT练手题,包含了所有的多项式基本运算呢 其中一部分解法参考了myy的uoj的blog 二分图计数 1: 实际是求所有图的二分图染色方案和 我们不妨枚举这个图中有多少个黑点 在n个点中 ...

  7. 3 Steps(二分图)

    C - 3 Steps Time limit : 2sec / Memory limit : 256MB Score : 500 points Problem Statement Rng has a ...

  8. 虚拟化构建二分图(BZOJ2080 题解+浅谈几道双栈排序思想的题)

    虚拟化构建二分图 ------BZOJ2080 题解+浅谈几道双栈排序思想的题 本题的题解在最下面↓↓↓ 不得不说,第一次接触类似于双栈排序的这种题,是在BZOJ的五月月赛上. [BZOJ4881][ ...

  9. [POJ2942]Knights of the Round Table(点双+二分图判定——染色法)

    建补图,是两个不仇恨的骑士连边,如果有环,则可以凑成一桌和谐的打麻将 不能直接缩点,因为直接缩点求的是连通分量,点双缩点只是把环缩起来 普通缩点                             ...

随机推荐

  1. yii框架里DetailView视图和GridView的区别

    1,首先从语义上分析 DetailView是数据视图,用于显示一条记录的数据,相当于网页中的详情页 GridView是网格视图,用于显示数据表里的所有记录,相当于网页里的列表页 2.用法上的区别 首先 ...

  2. win add static arp

    win add static arp > arp -s "192.168.0.2" "00-0a-35-01-fe-c0" > arp -a | f ...

  3. SpringBoot中yml配置文件

    1.yml配置文件书写格式 格式是在普通配置文件中以“.”分割的属性名称,该为“: ”和换行. 例子: //普通格式 spring.datasource.driver-class-name=com.m ...

  4. PE系统——安装教程

    本教程使用到的软件我会在本文末给出,若失效了请私信我,重新上传. 1.安装PE系统前,把U盘插在电脑上(如果你需要安装Windows10系统,请插入一个容量至少8G的U盘).当然容量最好是32—64G ...

  5. Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型

    Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型 一丶互斥锁 含义: ​ ​ ​ 每个对象都对应于一个可称为" 互斥锁&qu ...

  6. angular http interceptors 拦截器使用分享

    拦截器 在开始创建拦截器之前,一定要了解 $q和延期承诺api 出于全局错误处理,身份验证或请求的任何同步或异步预处理或响应的后处理目的,希望能够在将请求移交给服务器之前拦截请求,并在将请求移交给服务 ...

  7. 基于gtk的imshow:用gtk读取并显示图像

    gtk实现imshow,最naive的做法是用gtk的组件去读取图像,然后show出来:后续再考虑用GTK显示用别的方式例如stb image读取的图像.先前基于GDI实现imshow时也是这一思路, ...

  8. 树莓派安装系统+ssh登录

    一.准备工作: (1)树莓派3b (2)官网下载系统 (3)SD卡 (4)网线 (5)SDFormatter.exe (6)win32diskimager.exe (7)putty (7)笔记本 二. ...

  9. 攻防世界WEB高手进阶之python_template_injection

    python模板注入 看了一堆文章,也不是看的很明白,反而把题目做出来了 大概思路如下 简单探测 http://111.198.29.45:42611/{{7+7}} 返回 说明服务器执行了{{}}里 ...

  10. Tarjan算法分解强连通分量(附详细参考文章)

    Tarjan算法分解强连通分量 算法思路: 算法通过dfs遍历整个连通分量,并在遍历过程中给每个点打上两个记号:一个是时间戳,即首次访问到节点i的时刻,另一个是节点u的某一个祖先被访问的最早时刻. 时 ...