zoukankan      html  css  js  c++  java
  • CF 600F( 二分图

    题目:给一个二分图,对每条边进行染色,求一种使得相邻边颜色都不同并且所用颜色最少的染色方案.

    思路:颜色最少个数大于等于度最大的点的度数,然后要构造出一种染色方案.构造方法类似于二分匹配的搜索算法.对于每个点,记录与这个点相连的对应颜色的点,然后每次取最小的没有使用的颜色,如果颜色有冲突,对于两个点x,y,有cx没有在x的邻边出现,cy没有在y的邻边出现,把xy染成cx,然后冲突的边染色成cy,如果还有冲突,则用cx继续染色,由于是二分图没有奇环,所以必然可以最终找到替代方案.写法上有些技巧,参考了cf上红名巨巨的代码.

    /*
    * 没有过去,也没有未来
    */
    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <functional>
    #include <set>
    #include <cmath>
    using namespace std;
    #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0)
    #define pb push_back
    #define PB pop_back
    #define bk back()
    #define fs first
    #define se second
    #define sq(x) (x)*(x)
    #define eps (1e-10)
    #define INF (0x3f3f3f3f)
    #define clr(x) memset((x),0,sizeof (x))
    #define cp(a,b) memcpy((a),(b),sizeof (b))
    
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<ll,ll> P;
    
    const int maxn=1005;
    int linkx[maxn][maxn],linky[maxn][maxn];
    int id[maxn][maxn];
    int d[maxn*3];
    int a,b,m;
    int ans[maxn*maxn];
    int main(){
       //freopen("/home/slyfc/CppFiles/in","r",stdin);
        //freopen("/home/slyfc/CppFiles/out","w",stdout);
        memset(linkx,-1,sizeof linkx);
        memset(linky,-1,sizeof linky);
        memset(id,-1,sizeof id);
        cin>>a>>b>>m;
        int maxd=0;
        for(int e=0;e<m;e++){
            int x,y;
            scanf("%d%d",&x,&y);
            d[x]++,d[y+a]++;
            maxd=max(maxd,d[x]);
            maxd=max(maxd,d[y+a]);
            id[x][y]=e;
            int cx=0,cy=0;
            while(linkx[x][cx]!=-1) cx++;
            while(linky[y][cy]!=-1) cy++;
            if(cx==cy){
                linkx[x][cx]=y;
                linky[y][cy]=x;
            }else{
                int left=x;
                int right=y;
                linkx[x][cx]=y;
                for(;;){
                    int tmp=linky[right][cx];
                    linky[right][cx]=left;
                    linky[right][cy]=tmp;
                    if(tmp==-1) break;
                    int tmp0=linkx[tmp][cy];
                    linkx[tmp][cy]=right;
                    linkx[tmp][cx]=tmp0;
                    if(tmp0==-1) break;
                    left=tmp,right=tmp0;
                }
                
            }
        }
        cout<<maxd<<endl;
        for(int i=0;i<maxn;i++){
            for(int j=0;j<maxn;j++){
                if(linkx[i][j]!=-1){
                    int y=linkx[i][j];
                    ans[id[i][y]]=j+1;
                }
            }
        }
        for(int i=0;i<m;i++){
            printf("%d ",ans[i]);
        }
        return 0;    
    }
    View Code
  • 相关阅读:
    KMP算法精髓
    习题
    JavaScript function函数种类介绍
    街景地图 API
    电脑网卡
    框架的设计之IRepository还是IRepository<T>
    顺序线性表
    hdu4284之字典树
    pt-table-checksum
    C++中输入输出流及文件流操作笔记
  • 原文地址:https://www.cnblogs.com/Cw-trip/p/5010462.html
Copyright © 2011-2022 走看看