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
  • 相关阅读:
    CodeForces 7B
    CodeForces 4D
    离散化
    线段树入门
    洛谷 P3951 小凯的疑惑(赛瓦维斯特定理)
    Codeforces 1295D Same GCDs (欧拉函数)
    Codeforces 1295C Obtain The String (二分)
    Codeforces 1295B Infinite Prefixes
    Codeforces 1295A Display The Number(思维)
    Codeforces 1294F Three Paths on a Tree(树的直径,思维)
  • 原文地址:https://www.cnblogs.com/Cw-trip/p/5010462.html
Copyright © 2011-2022 走看看