• CodeForces 547D Mike and Fish


    CodeForces 547D Mike and Fish

    https://codeforces.com/contest/547/problem/D

    UY6NBF.png

    Tutorial

    https://codeforces.com/blog/entry/18126

    二分图,左右分别有(2 imes 10^5)个节点,一共有(n)条边,将每条边染上红色或蓝色,使得每个点相邻的不同颜色的边数量差绝对值小于等于1

    考虑如果图中只有偶度点,找到欧拉回路,由于是环,所以相邻边染不同颜色就可以不影响每个点的相邻不同色边差的情况下完成染色.

    假如图中有奇度点,那么一定存在它到另一个奇度点的路径,那么将这条路径找出来,相邻边染不同颜色,那么只会有这两个奇度点的差发生变化,而且由于这样之后它们就是偶度点了,所以今后也不会变化.

    具体实现可以每次找出一个奇度点(u),然后删掉任意删掉一条与它相邻的边(v),在解决掉删掉之后的子问题后,根据(v)当前的差的情况选择这条边的颜色.因为观察算法过程,发现修改(v)的颜色比修改(u)的颜色更优((u)之前更有可能有别的删去的边)

    Code

    #include <cstdio>
    #include <iostream>
    #include <set>
    #include <vector>
    #define debug(...) fprintf(stderr,__VA_ARGS__)
    #define fi first
    #define se second
    using namespace std;
    inline char gc() {
    	return getchar();
    	static char buf[100000],*l=buf,*r=buf;
    	return l==r&&(r=(l=buf)+fread(buf,1,100000,stdin),l==r)?EOF:*l++;
    }
    template<class T> void rd(T &x) {
    	x=0; int f=1,ch=gc();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
    	while(ch>='0'&&ch<='9'){x=x*10-'0'+ch;ch=gc();}
    	x*=f;
    }
    const int maxn=2e5+50,maxN=4e5+50;
    const int N=4e5;
    int n,an[maxn];
    int deg[maxN];
    set<int> s[2];
    set< pair<int,int> > E[maxN];
    vector<int> R;
    struct node {
    	int u,v,id;
    	node(int u=0,int v=0,int id=0):u(u),v(v),id(id){}
    };
    vector<node> rec;
    inline void addedge(int u,int v,int id) {
    	E[u].insert(make_pair(v,id));
    	E[v].insert(make_pair(u,id));
    }
    inline void del(int u,int v,int id) {
    	s[E[u].size()&1].erase(u);	
    	E[u].erase(make_pair(v,id));
    	s[E[u].size()&1].insert(u);
    }
    void dfs(int u) {
    	while(E[u].size()) {
    		int v=E[u].begin()->fi,id=E[u].begin()->se;
    		E[u].erase(E[u].begin()),E[v].erase(make_pair(u,id));
    		dfs(v);
    		R.push_back(id);
    	}
    }
    int main() {
    	rd(n);
    	for(int i=1;i<=n;++i) {
    		int x,y; rd(x),rd(y),y+=2e5;
    		addedge(x,y,i);
    	}
    	for(int i=1;i<=N;++i) s[E[i].size()&1].insert(i);
    	while(s[1].size()) {
    		int u=*s[1].begin();
    		int v=E[u].begin()->fi,id=E[u].begin()->se;
    		rec.push_back(node(u,v,id));
    		del(u,v,id),del(v,u,id);
    	}
    	for(int i=1;i<=N;++i) if(E[i].size()) dfs(i);
    	for(int i=0;i<R.size();++i) an[R[i]]=i&1;
    	for(int i=rec.size()-1;~i;--i) {
    		int u=rec[i].u,v=rec[i].v,id=rec[i].id;
    		if(deg[v]>0) an[id]=0,--deg[u],--deg[v];
    		else an[id]=1,++deg[u],++deg[v];
    	}
    	for(int i=1;i<=n;++i) printf("%c",an[i]?'r':'b');
    	printf("
    ");
    	return 0;
    }
    
  • 相关阅读:
    getElementsByTagName 与 $(élement)的区别
    php面向对象学习笔记
    使用php添加定时任务
    JS中数组Array的用法
    大陆居民身份证真伪校验
    安卓 日常问题 工作日志15
    安卓 日常问题 工作日志14
    安卓 日常问题 工作日志13
    安卓 日常问题 工作日志12
    安卓 日常问题 工作日志11
  • 原文地址:https://www.cnblogs.com/ljzalc1022/p/13295404.html
Copyright © 2020-2023  润新知