zoukankan      html  css  js  c++  java
  • CF1364D Solution

    题目链接

    题解

    依题目所述,2种完成方法一定可以满足一种,以下为简单证明:若图中存在简单环,设该环长度为\(l\)。若\(l\le k\),则满足条件1;若\(l>k\),间隔取点可以得到包含\(\lfloor \frac{l}{2}\rfloor\)个点的独立集,又因为\(\lfloor \frac{l}{2}\rfloor\ge \lceil \frac{k}{2}\rceil\),满足条件2。如果图中不存在环,则该图为二分图(树),一定满足条件1。

    上述证明正可以成为我们的解题思路(出题人伏笔妙a),具体实现:dfs找出图中的一个环,利用栈记录搜索到的全部节点,如果同一节点经过2次则判断为环,递归后回溯则可保证不会出现多余节点。如果没有找到环说明这是一棵树,黑白染色(使节点与其祖先不为同一颜色)后取节点数较多的颜色输出即可。如果找到环的话,仍需注意我们记录的只是节点,其可能构成的不是简单环。为此遍历所有环中的节点,如果其存在一条不在环中的边通向环中其他节点,则将该边另一侧全部节点删去,将此边加入。对于找出的简单环,若\(l>k\)则隔一个点输出一个(条件2),若\(l\le k\)则直接将该环输出(条件1)。

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10,M=2e5+10;
    int fst[N],nxt[2*M],v[2*M],cnt;
    int st[N],top;
    int r[N];
    bool vis[N],c[N];
    void add(int x,int y)
    {
    	v[++cnt]=y;
    	nxt[cnt]=fst[x]; fst[x]=cnt;
    }
    bool dfs(int x,int fa)
    {
    	st[++top]=x;
    	if(vis[x]) return 1;
    	vis[x]=1;
    	for(int i=fst[x];i;i=nxt[i])
    	{
    		int y=v[i];
    		if(y==fa) continue; 
    		if(dfs(y,x)) return 1;
    	} 
    	top--; vis[x]=0;
    	return 0;
    }
    void dfs2(int x,int fa)
    {
    	for(int i=fst[x];i;i=nxt[i])
    	{
    		int y=v[i];
    		if(y!=fa) {c[y]=c[x]^1; dfs2(y,x);}
    	}
    }
    int main()
    {
    	int n,m,k;
    	scanf("%d%d%d",&n,&m,&k);
    	int x,y,sum=0;
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%d%d",&x,&y);
    		add(x,y),add(y,x); 
    	}
    	if(!dfs(1,0))
    	{
    		printf("1\n");
    		c[1]=0; dfs2(1,0);
    		for(int i=1;i<=n;i++) sum+=c[i];
    		k=(k+1)/2;
    		if(sum>=k)
    		{
    			for(int i=1;i<=n && k;i++)
    				if(c[i]) {printf("%d ",i); k--;}
    			return 0;
    		}
    		for(int i=1;i<=n && k;i++)
    			if(!c[i]) {printf("%d ",i); k--;}
    		return 0;
    	}
    	int qwq=st[top],tot=0;  
    	while(st[--top]!=qwq) r[st[top]]=st[top+1],c[st[top]]=1;
    	c[qwq]=1,r[qwq]=st[top+1];
    	for(int i=1;i<=n;i++)
    	{
    		if(!c[i]) continue;
    		for(int j=fst[i];j;j=nxt[j])
    		{
    			int y=v[j],pos=r[y];
    			if(!c[y] || y==r[i] || r[y]==i) continue;
    			while(pos!=i) {c[pos]=0; pos=r[pos];}
    			r[y]=i;
    		}
    	}
    	for(int i=1;i<=n;i++) 
    	{
    		tot+=c[i];
    		if(c[i]) qwq=i; 
    	}
    	if(tot>k)
    	{
    		printf("1\n"); k=(k+1)/2;
    		while(k--) {printf("%d ",qwq); qwq=r[r[qwq]];}
    		return 0;
    	}
    	printf("2\n%d\n%d ",tot,qwq);
    	int pos=r[qwq];
    	while(pos!=qwq) {printf("%d ",pos); pos=r[pos];}
    	return 0;
    }
    
  • 相关阅读:
    js中的原生Ajax和JQuery中的Ajax
    this的用法
    static的特性
    时政20180807
    java compiler没有1.8怎么办
    Description Resource Path Location Type Java compiler level does not match the version of the installed Java project facet Unknown Faceted Project Problem (Java Version Mismatch)
    分词器
    [数算]有一个工程甲、乙、丙单独做,分别要48天、72天、96天完成
    一点感想
    解析Excel文件 Apache POI框架使用
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14449692.html
Copyright © 2011-2022 走看看