HDU7074 Little prince and the garden of roses

HDU7074 Little prince and the garden of roses

首先可以对于每一个颜色分别考虑。

如果存在与\((i,j)\),就在\(i,j+n\)中间连一条边。

形成一个二分图。

你需要给每一个二分图染色,使得颜色相同的边不能公用一个顶点。

有一个经典结论,颜色数即为最大度数。

首先这个很显然可以网络流,每次找一个最大匹配,但是这样复杂度是\(O(N^3\sqrt N)\)的,会\(TLE\)

考虑一种调整方法。

首先一条边一条边考虑。

假设当前需要将边\((u,v)\)染色。

如果\(u,v\)都不含有颜色\(x\),则将\((u,v)\)染成\(x\)

否则找到一个\(u\)不含有的颜色\(x\),\(v\)不含有的颜色\(y\)

\((u,v)\)​染成\(x\)​。

然后需要将\(v\)​原来连着的\(x\)​改成\(y\)​。

然后一路调整下去。

可以发现这条链是无环的。

所以时间复杂度是\(O(N^3)\)

#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
//inline int read(){
//    int x=0;
//    char ch=getchar();
//    while(ch<'0'||ch>'9'){
//        ch=getchar();
//    }
//    while(ch>='0'&&ch<='9'){
//        x=(x<<1)+(x<<3)+(ch^48);
//        ch=getchar();
//    }
//    return x;
//}
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
const int MAXN=3e2+1;
int n,c[MAXN][MAXN];
vector<mp> pos[MAXN*MAXN];
int pt[MAXN*2][MAXN];
int deg[MAXN*2];
vector<pair<mp,int> > path;
void modify(int now,int x,int y){//x->y
    if(pt[now][x]==-1){
        return ;
    }
    path.PB(II(II(pt[now][x],now),y));
    int nx=pt[now][x];
    pt[now][x]=-1;
    pt[nx][x]=-1;
    modify(nx,y,x);
}
void solve(){
    scanf("%d",&n);
    rb(i,1,n) rb(j,1,n) scanf("%d",&c[i][j]);
    rb(i,1,n*n) pos[i].clear();
    rb(i,1,n) rb(j,1,n) pos[c[i][j]].PB(II(i,j));
    int answer1=0;
    vector<pair<mp,int > > answer2;
    rb(i,1,n*n){
        if(pos[i].size()==0) continue;
        rb(j,1,n*2) deg[j]=0;
        int D=0;
        vector<mp> edges;
        for(auto it:pos[i]){
            edges.PB(II(it.FIR,it.SEC+n));
            deg[it.FIR]++;
            deg[it.SEC+n]++;
        }
        D=*max_element(deg+1,deg+1+n+n);
        check_max(answer1,D-1);
        if(D==1) continue;
        rep(k,D){
            rb(j,1,n*2) pt[j][k]=-1;
        }
        for(auto it_:edges){
            int u,v;
            u=it_.FIR;
            v=it_.SEC;
//            cout<<u<<' '<<v<<endl;
            int ok=-1;
            rep(k,D){
                if(pt[u][k]==-1&&pt[v][k]==-1){
                    ok=k;
                    break;
                }
            }
            if(ok!=-1){
                pt[u][ok]=v;
                pt[v][ok]=u;
                continue;
            }
            int x,y;
            rep(k,D){
                if(pt[u][k]==-1){
                    x=k;
                }
                if(pt[v][k]==-1){
                    y=k;
                }
            }
            path.clear();
            modify(v,x,y);
            pt[u][x]=v;
            pt[v][x]=u;
            for(auto it:path){
                pt[it.FIR.FIR][it.SEC]=it.FIR.SEC;
                pt[it.FIR.SEC][it.SEC]=it.FIR.FIR;
            }
        }
        rb(i,1,n){
            rep(k,D){
                if(k&&pt[i][k]!=-1){
                    answer2.PB(II(II(i,pt[i][k]-n),k));
                }
            }
        }
    }
    printf("%d %d\n",answer1,(int)(answer2.size()));
    for(auto it:answer2){
        printf("%d %d %d\n",it.FIR.FIR,it.FIR.SEC,it.SEC);
    }  
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--) solve();   
    return 0;
}
posted @ 2021-08-20 12:42  WWW~~~  阅读(24)  评论(0编辑  收藏  举报