• codeforces #305 D Mike and Fish


    正解貌似是大暴搜?

    首先我们考虑这是一个二分图,建立网络流模型后很容易得出一个算法

    S->行 容量为Num[X]/2;

    行->列 容量为1 且要求(x,y)这个点存在

    列->T 容量为Num[Y]/2

    这样子跑网络流之后我们就得到了一组解

    但是我们考虑输出方案

    对于每一行,如果Num[X]为偶数,那么显然输出方案是正确的

    但是如果Num[x]为奇数,多出的那个显然既有可能是红的也可能是蓝的

    但关键是我们不能确定他是红的或者蓝的,因为他的状态也会影响对应的列

    同样,列的考虑也是同理

    所以我们对于残量网络,如果Num[X]或者Num[Y]是奇数,那么就连对应的容量为1的边

    对残量网络在进行一次网络流,这样就可以输出方案辣

    (话说网络流跑40w的点居然一点也不虚)

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #define h(i) i
    #define l(i) i+200000
    using namespace std;
    
    const int maxn=200010;
    const int oo=0x7fffffff;
    int S,T;
    int n,cntx,cnty;
    int X[maxn],Y[maxn];
    int NX[maxn],NY[maxn];
    int idx[maxn],idy[maxn];
    bool visx[maxn],visy[maxn];
    int h[maxn<<1],cnt=1;
    int cur[maxn<<1];
    struct edge{
    	int to,next,w;
    }G[4000010];
    int vis[maxn<<1];
    queue<int>Q;
    
    void add(int x,int y,int z){
    	++cnt;
    	G[cnt].to=y;G[cnt].next=h[x];G[cnt].w=z;h[x]=cnt;
    	++cnt;
    	G[cnt].to=x;G[cnt].next=h[y];G[cnt].w=0;h[y]=cnt;
    }
    void read(int &num){
    	num=0;char ch=getchar();
    	while(ch<'!')ch=getchar();
    	while(ch>='0'&&ch<='9')num=num*10+ch-'0',ch=getchar();
    }
    bool BFS(){
    	memset(vis,-1,sizeof(vis));
    	Q.push(S);vis[S]=1;
    	while(!Q.empty()){
    		int u=Q.front();Q.pop();
    		for(int i=h[u];i;i=G[i].next){
    			int v=G[i].to;
    			if(vis[v]==-1&&G[i].w>0){
    				vis[v]=vis[u]+1;
    				Q.push(v);
    			}
    		}
    	}return vis[T]!=-1;
    }
    int DFS(int x,int f){
    	if(x==T||f==0)return f;
    	int w,used=0;
    	for(int i=cur[x];i;i=G[i].next){
    		if(vis[G[i].to]==vis[x]+1){
    			w=f-used;
    			w=DFS(G[i].to,min(w,G[i].w));
    			G[i].w-=w;G[i^1].w+=w;
    			if(G[i].w>0)cur[x]=i;
    			used+=w;if(used==f)return used;
    		}
    	}
    	if(!used)vis[x]=-1;
    	return used;
    }
    void dinic(){
    	while(BFS()){
    		for(int i=S;i<=T;++i)cur[i]=h[i];
    		DFS(S,oo);
    	}return;
    }
    
    int main(){
    	read(n);S=0;T=400001;
    	for(int i=1;i<=n;++i){
    		read(X[i]);read(Y[i]);
    		NX[X[i]]++;NY[Y[i]]++;
    	}
    	for(int i=1;i<=n;++i)add(h(X[i]),l(Y[i]),1);
    	for(int i=1;i<=n;++i){
    		if(!visx[X[i]]){
    			add(S,h(X[i]),NX[X[i]]>>1);
    			visx[X[i]]=true;
    		}
    		if(!visy[Y[i]]){
    			add(l(Y[i]),T,NY[Y[i]]>>1);
    			visy[Y[i]]=true;
    		}
    	}
    	dinic();
    	memset(visx,false,sizeof(visx));
    	memset(visy,false,sizeof(visy));
    	for(int i=1;i<=n;++i){
    		if(!visx[X[i]]){
    			visx[X[i]]=true;
    			if(NX[X[i]]&1)add(S,h(X[i]),1);
    		}
    		if(!visy[Y[i]]){
    			visy[Y[i]]=true;
    			if(NY[Y[i]]&1)add(l(Y[i]),T,1);
    		}
    	}
    	dinic();
    	for(int i=1;i<=n;++i){
    		if(!G[(i<<1)+1].w)printf("b");
    		else printf("r");
    	}return 0;
    }
    

      

  • 相关阅读:
    写在连载之前——DIY微型操作系统篇
    footer始终在页面最底部的方法(问题待检验)
    各种二级菜单代码
    复选框已经有checked,但是页面没有选中效果(解决)
    px em rem 的区别
    marquee标签详解
    Docker:正常运行的容器突然端口不通一般检查方法
    linux中 vm.overcommit_memory 的含义
    redis6 redis-cli cluster的使用总结
    利用Java反射机制优化简单工厂设计模式
  • 原文地址:https://www.cnblogs.com/joyouth/p/5352888.html
Copyright © 2020-2023  润新知