zoukankan      html  css  js  c++  java
  • UVA-10615 Rooks (二分图匹配)

    题目大意:在一个nxn的方格中,有些位置有车,要给每一个车都涂上颜色,使得同一行和同一列的任意两个车颜色不同,求一种需要颜色种数最少的涂色方案。

    题目分析:所需的最少颜色种数是显然就能得出的,假设最少颜色种数为k。如果位置(i,j)是车,那么连一条边i->j,得到一张二分图,进行k次匹配即可构造出解。

    AC代码:

    # include<iostream>
    # include<cstdio>
    # include<vector>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    # define REP(i,s,n) for(int i=s;i<n;++i)
    # define CL(a,b) memset(a,b,sizeof(a))
    # define CLL(a,b,n) fill(a,a+n,b)
    
    const int N=105;
    int inr[N],inc[N],vis[N],link[N],ans[N][N],n;
    char p[N][N];
    vector<int>G[N];
    
    bool dfs(int x)
    {
        REP(i,0,G[x].size()){
            int y=G[x][i];
            if(vis[y]) continue;
            vis[y]=1;
            if(link[y]==-1||dfs(link[y])){
                link[y]=x;
                return true;
            }
        }
        return false;
    }
    
    void match()
    {
        CL(link,-1);
        REP(i,0,n){
            CL(vis,0);
            dfs(i);
        }
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            REP(i,0,n) G[i].clear();
            REP(i,0,n) scanf("%s",p[i]);
            CL(inr,0);
            CL(inc,0);
            REP(i,0,n) REP(j,0,n) if(p[i][j]=='*'){
                ++inr[i];
                ++inc[j];
                G[i].push_back(j);
            }
    
            int maxn=0;
            REP(i,0,n) maxn=max(maxn,max(inr[i],inc[i]));
    
            REP(i,0,n) if(inr[i]<maxn){
                for(int j=0;j<n&&inr[i]<maxn;++j){
                    while(inr[i]<maxn&&inc[j]<maxn){
                        ++inr[i];
                        ++inc[j];
                        G[i].push_back(j);
                    }
                }
            }
    
            CL(ans,0);
            REP(k,1,maxn+1){
                match();
                REP(i,0,n){
                    int r=link[i];
                    if(p[r][i]=='*') ans[r][i]=k;
                    REP(j,0,G[r].size()) if(G[r][j]==i){
                        G[r].erase(G[r].begin()+j);
                        break;
                    }
                }
            }
    
            printf("%d
    ",maxn);
            REP(i,0,n) REP(j,0,n) printf("%d%c",ans[i][j],(j==n-1)?'
    ':' ');
        }
        return 0;
    }
    

      

  • 相关阅读:
    FreeSWITCH一些需求应对
    CentOS 7安装Mysql并设置开机自启动
    RTP学习笔记
    SDP学习笔记
    Quartz实用二三事
    Quartz:ERROR threw an unhandled Exception
    CentOS 7一些常用配置
    Java获取音频文件(MP3)的播放时长
    使用Callable和Future接口创建线程
    join() 方法详解及应用场景
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4948056.html
Copyright © 2011-2022 走看看