• 7.9 NOI模拟赛 A.图 构造 dfs树 二分图


    avatar
    avatar
    avatar

    啥都想不出来的我是不是废了/dk

    这道题考的主要是构造 而我想的主要是乱搞。

    一个很假很假的做法:直接暴力4种颜色染色 我也不知道对不对。。 不过成功的话一定是对的。

    然后考虑奇环的问题 一个很假很假的做法 建立出dfs树然后 然后利用返祖边+倍增做奇环的问题 主要考察环上所有的点的入度都>2。

    显然 很多环都没有被便利到 所以这个做法是很假的。

    好像多random几次能A?当然不行!接下来是否联通也存在问题 这个做法假死了 当然如果不嫌麻烦可以check且再次随机 暴力出奇迹嘛~!

    然而水到了60

    考虑正解 容易想到正解一定是两种解其中的一个 第一个解没有什么好的处理方法。

    考虑奇环->二分图 那么其实我们可以先随便找到一棵树 然后先保证联通看剩下的东西是否是一个二分图。

    如果不是 那么就存在奇环了 去掉且此时是联通的 如果不存在显然树可以用两个颜色染色 二分图也是如此 那么四颜色染色就派上用场了。

    所以这个问题是一定有解的 至此问题得到解决。

    考虑选取的树不同是否对答案造成影响 显然不会 因为这种构造方法使得什么情况都有解。

    我也只能甘拜下风了。。

    bf code
    //#include<bitsstdc++.h>
    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<ctime>
    #include<cmath>
    #include<cctype>
    #include<cstdlib>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<vector>
    #include<algorithm>
    #include<utility>
    #include<bitset>
    #include<set>
    #include<map>
    #define ll long long
    #define db double
    #define INF 10000000000000010ll
    #define ldb long double
    #define pb push_back
    #define put_(x) printf("%d ",x);
    #define get(x) x=read()
    #define gt(x) scanf("%d",&x)
    #define gi(x) scanf("%lf",&x)
    #define put(x) printf("%d
    ",x)
    #define putl(x) printf("%lld
    ",x)
    #define gc(a) scanf("%s",a+1)
    #define rep(p,n,i) for(RE int i=p;i<=n;++i)
    #define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
    #define fep(n,p,i) for(RE int i=n;i>=p;--i)
    #define vep(p,n,i) for(RE int i=p;i<n;++i)
    #define pii pair<int,int>
    #define mk make_pair
    #define RE register
    #define P 1000000007
    #define gf(x) scanf("%lf",&x)
    #define pf(x) ((x)*(x))
    #define uint unsigned long long
    #define ui unsigned
    #define EPS 1e-8
    #define sq sqrt
    #define S second
    #define F first
    #define mod 998244353
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc()
    {
        return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
        RE int x=0,f=1;RE char ch=getc();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
        while(ch>='0'&&ch<='9'){x=((ll)x*10+ch-'0')%mod;ch=getc();}
        return x*f;
    }
    const int MAXN=300010,maxn=100010;
    int n,m,ans,len,flag,cnt,top;
    int vis[MAXN],c[MAXN],col[5],ans1[MAXN],dfn[MAXN],f[MAXN][20],Log[MAXN],g[MAXN][20],ru[MAXN];
    int lin[MAXN],ver[MAXN<<1],nex[MAXN<<1],d[MAXN];
    inline void add(int x,int y)
    {
    	ver[++len]=y;
    	nex[len]=lin[x];
    	lin[x]=len;
    	++ru[x];
    }
    inline void dfs(int x)
    {
    	if(flag)return;
    	vis[x]=1;col[1]=col[2]=col[3]=col[4]=0;
    	go(x)++col[c[tn]];
    	int ww=1;while(ww<=4&&col[ww])++ww;
    	if(ww<=4)c[x]=ww;else {flag=1;return;}
    	go(x)if(!vis[tn])dfs(tn);
    }
    inline void dfs1(int x,int fa)//建立dfs树.
    {
    	dfn[x]=++cnt;d[x]=d[fa]+1;
    	f[x][0]=fa;g[x][0]=ru[x];
    	rep(1,Log[d[x]],i)
    	{
    		f[x][i]=f[f[x][i-1]][i-1];
    		g[x][i]=min(g[x][i-1],g[f[x][i-1]][i-1]);
    	}
    	go(x)if(!dfn[tn])dfs1(tn,x);
    }
    inline int check(int x,int y)
    {
    	int mx=ru[x];
    	fep(Log[d[x]],0,i)if(d[f[x][i]]>=d[y])mx=min(mx,g[x][i]),x=f[x][i];
    	return mx>2;
    }
    inline void dp(int x)
    {
    	//if(top)return;
    	go(x)
    	{
    		if(dfn[tn]<dfn[x])
    		{
    			if(top)continue;
    			if((d[x]-d[tn]+1)&1)
    			{
    				if(check(x,tn))
    				{
    					int ww=x;
    					ans1[++top]=x;
    					while(ww!=tn)
    					{
    						ans1[++top]=f[ww][0];
    						ww=f[ww][0];
    					}
    				}
    			}
    		}
    		else if(dfn[tn]==dfn[x]+1)dp(tn);
    	}
    }
    int main()
    {
    	freopen("g.in","r",stdin);
    	freopen("g.out","w",stdout);
    	get(n);get(m);
    	rep(1,m,i)
    	{
    		int get(x),get(y);
    		add(x,y);add(y,x);
    	}
    	dfs(1);
    	if(!flag)
    	{
    		printf("A");
    		rep(1,n,i)printf(" %d",c[i]);
    		return 0;
    	}
    	else
    	{
    		rep(2,n,i)Log[i]=Log[i>>1]+1;
    		dfs1(1,0);
    		dp(1);
    		if(top)
    		{
    			printf("B");printf(" %d",top);
    			rep(1,top,i)printf(" %d",ans1[i]);
    			return 0;
    		}
    		puts("wxh ak ioi2019");
    	}
    	return 0;
    }
    
    sol code
    //#include<bitsstdc++.h>
    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<ctime>
    #include<cmath>
    #include<cctype>
    #include<cstdlib>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<vector>
    #include<algorithm>
    #include<utility>
    #include<bitset>
    #include<set>
    #include<map>
    #define ll long long
    #define db double
    #define INF 10000000000000010ll
    #define ldb long double
    #define pb push_back
    #define put_(x) printf("%d ",x);
    #define get(x) x=read()
    #define gt(x) scanf("%d",&x)
    #define gi(x) scanf("%lf",&x)
    #define put(x) printf("%d
    ",x)
    #define putl(x) printf("%lld
    ",x)
    #define gc(a) scanf("%s",a+1)
    #define rep(p,n,i) for(RE int i=p;i<=n;++i)
    #define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
    #define fep(n,p,i) for(RE int i=n;i>=p;--i)
    #define vep(p,n,i) for(RE int i=p;i<n;++i)
    #define pii pair<int,int>
    #define mk make_pair
    #define RE register
    #define P 1000000007
    #define gf(x) scanf("%lf",&x)
    #define pf(x) ((x)*(x))
    #define uint unsigned long long
    #define ui unsigned
    #define EPS 1e-8
    #define sq sqrt
    #define S second
    #define F first
    #define mod 998244353
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc()
    {
        return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
        RE int x=0,f=1;RE char ch=getc();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
        while(ch>='0'&&ch<='9'){x=((ll)x*10+ch-'0')%mod;ch=getc();}
        return x*f;
    }
    const int MAXN=300010,maxn=100010;
    int n,m,ans,len=1,flag,cnt,top,A,B;
    int vis[MAXN],c1[MAXN],c2[MAXN],mark[MAXN<<1];
    int lin[MAXN],ver[MAXN<<1],nex[MAXN<<1],ans1[MAXN],f[MAXN];
    inline void add(int x,int y)
    {
    	ver[++len]=y;
    	nex[len]=lin[x];
    	lin[x]=len;
    }
    inline void dfs(int x)
    {
    	vis[x]=1;
    	go(x)
    	{
    		if(vis[tn])continue;
    		mark[i]=mark[i^1]=1;
    		c1[tn]=c1[x]^1;
    		dfs(tn);
    	}
    }
    inline void dfs1(int x)
    {
    	vis[x]=1;
    	go(x)
    	{
    		if(mark[i])continue;
    		if(!vis[tn])
    		{
    			c2[tn]=c2[x]^1;
    			f[tn]=x;dfs1(tn);
    		}
    		else if(c2[tn]==c2[x]){A=tn,B=x;flag=1;}
    	}
    }
    int main()
    {
    	freopen("g.in","r",stdin);
    	freopen("g.out","w",stdout);
    	get(n);get(m);
    	rep(1,m,i)
    	{
    		int get(x),get(y);
    		add(x,y);add(y,x);
    	}
    	dfs(1);
    	memset(vis,0,sizeof(vis));
    	rep(1,n,i)if(!vis[i])dfs1(i);
    	if(!flag)
    	{
    		printf("A");
    		rep(1,n,i)printf(" %d",c1[i]*2+c2[i]+1);
    		return 0;
    	}
    	else
    	{
    		printf("B");
    		for(int i=A;i!=B;i=f[i])ans1[++top]=i;
    		ans1[++top]=B;
    		printf(" %d",top);
    		rep(1,top,i)printf(" %d",ans1[i]);
    		return 0;
    	}
    	puts("wxh ak ioi2019");
    	return 0;
    }
    
  • 相关阅读:
    字符串、组合数据类型练习
    使用python画五星红旗
    常用linux操作
    关于大数据
    简易C语言文法
    实验一 词法分析系统
    关于计算机编译原理
    七号团队-团队任务4:每日例会(2018-11-28)
    七号团队-团队任务4:每日例会(2018-11-27)
    第七组,团队作业2
  • 原文地址:https://www.cnblogs.com/chdy/p/13275640.html
Copyright © 2020-2023  润新知