zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    JAVA基础——编程练习(二)
    JAVA基础——面向对象三大特性:封装、继承、多态
    JVM内存
    50. Pow(x, n) (JAVA)
    47. Permutations II (JAVA)
    46. Permutations (JAVA)
    45. Jump Game II (JAVA)
    43. Multiply Strings (JAVA)
    42. Trapping Rain Water (JAVA)
    41. First Missing Positive (JAVA)
  • 原文地址:https://www.cnblogs.com/joyouth/p/5352888.html
Copyright © 2011-2022 走看看