zoukankan      html  css  js  c++  java
  • ! JOISC2020DAY2变色龙之恋

    二分图!



    一只变色龙与另外的变色龙颜色相同只可能有三种情况——喜欢,被喜欢和原颜色一样

    我们将这样的变色龙对连上边,那么因为性别不同的限定,一定是一个二分图

    这样可以二分,若加入(u)后颜色数不变那么这里面一定存在可以连边的变色龙对

    我们可以黑白染色然后分开二分,这样原集合大小即为颜色数

    得到之后,每个点再做两次即可找到喜欢的对象,排除后就剩下颜色相同的了

    #include "chameleon.h"
    #include<bits/stdc++.h>
    using namespace std;
    namespace mine{
    const int N=1e5+4;
    #define vi vector<int>
    vi e[N],ask;
    int n,col[N],v[2][N],vc[2],pre[N];
    bool b[N],use[N];
    void dfs(int x,int c){
    	col[x]=c;
    	for(auto v:e[x])
    		if(col[v]==-1)dfs(v,c^1);
    }
    inline void getcol(int i){
    	memset(col+1,-1,n<<2);
    	for(int j=1;j<i;j++)
    		if(col[j]==-1)dfs(j,0);
    	memset(vc,0,8);
    	for(int j=1;j<i;j++)v[col[j]][++vc[col[j]]]=j;
    } 
    inline bool ck(int p,int l,int r,int i){
    	ask.clear();ask.push_back(i);
    	for(int j=l;j<=r;j++)
    		if(!b[v[p][j]])ask.push_back(v[p][j]);
    	return Query(ask)<ask.size();
    }
    int query(int p,int l,int r,int i){
    	if(l==r)return v[p][l];
    	int mid=l+r>>1;
    	return ck(p,l,mid,i)?query(p,l,mid,i):query(p,mid+1,r,i); 
    }
    inline void solve(int nn){
    	n=nn<<1;
    	for(int i=1,x;i<=n;i++){
    		getcol(i);
    		memset(b+1,0,n);
    		for(int o=0;o<2;o++)
    			for(;ck(o,1,vc[o],i);){
    				x=query(o,1,vc[o],i);
    				e[i].push_back(x);
    				e[x].push_back(i);
    				b[x]=1;
    			}
    	}
    	ask.resize(3);
    	for(int i=1,x;i<=n;i++){
    		if(e[i].size()==1){
    			if(use[i])continue;
    			Answer(i,e[i][0]);
    			use[i]=use[e[i][0]]=1;
    			continue;
    		}
    		ask[0]=i;
    		ask[1]=e[i][0];ask[2]=e[i][1];x=Query(ask);
    		if(x==1){
    			swap(e[i][2],e[i][0]);
    			pre[e[i][0]]=i;
    			continue;
    		}
    		ask[2]=e[i][2];x=Query(ask);
    		if(x==1){
    			swap(e[i][1],e[i][0]);
    			pre[e[i][0]]=i;
    			continue;
    		}
    		pre[e[i][0]]=i;
    	}
    	for(int i=1,x;i<=n;i++){
    		if(use[i])continue;
    		if(pre[i]==e[i][1])x=e[i][2];
    		else x=e[i][1];
    		Answer(i,x);
    		use[i]=use[x]=1;
    	}
    }
    }
    void Solve(int N){
    	mine::solve(N);
    }
    
  • 相关阅读:
    python 内存泄漏——使用pymssql模块的讨论 free(): corrupted unsorted chunks
    Python的gc模块
    使用多线程——线程池
    sqlserver 数据库连接池
    drf response——简单封装
    邮箱找回密码实现
    阿里云 oss 服务 —— 上传图片,获取url
    dajngo-apscheduler 实现定时任务
    kubernetes基础概念
    Path must be a string.
  • 原文地址:https://www.cnblogs.com/aurora2004/p/12555434.html
Copyright © 2011-2022 走看看