WA on #23玄关求调
  • 板块CF19E Fairy
  • 楼主封禁用户
  • 当前回复2
  • 已保存回复3
  • 发布时间2025/1/13 21:19
  • 上次更新2025/6/18 19:24:12
查看原帖
WA on #23玄关求调
606278
封禁用户楼主2025/1/13 21:19
/*
CF19E
思路:
1.先进行判断,是否所有联通分量均为二分图,如果是,那么所有边都可以
2.如不是且有>1个不是,那么无解
3.如果刚好有一个,问题可视作在一个连通且不是二分图的图上进行运算
    1.回边的解:
        定义在dfs树上的回边如果是构成奇环的边则成为坏边,否则是好边。
        1.如果没有坏边,那么所有回边都是解(这种情况不可能因为这个图不是二分图)
        2.如果有恰好一条坏边,那么这条坏边即为唯一解
        3.如果有>1条坏边,那么无解
    2.树边的解:
        这里的奇环是指只包括一条返祖边且包括奇数条边的环,偶环同理
        1.同时在所有奇环上且不在任何一个偶环上的边,使用差分进行判断即可。
*/
// 1<=n<=1e4 0<=m<=1e4 1<=v<=n 1<=u<=n
#include<bits/stdc++.h>
using namespace std;
const int MAXN=2e4+4;

int n,m,u[MAXN],v[MAXN],siz=0,siz1=1,dfn[MAXN],dep[MAXN],cha1[MAXN],cha2[MAXN],sum=0;
vector<int> e[MAXN];
int col[MAXN];
vector<int> notc,badid,ans;

bool is_two(int id,int fa){
	if (col[id]==col[fa]) return 0;
	if (col[id]) return 1;
	col[id]=-col[fa];
	for (int tmp:e[id]){
		int i=v[tmp];
		if (i!=fa and !is_two(i,id)) return 0;
	}
	return 1;
}

void dfs(int id,int in_e){
	dfn[id]=++siz;
	dep[id]=dep[u[in_e]]+1;
	for (int tmp:e[id]){
		int i=v[tmp];
		if (!dfn[i]){
			dfs(i,tmp);
		}
		else if (in_e!=(tmp^1) and dfn[id]>dfn[i]){
			if ((dep[id]-dep[i])%2==0) badid.push_back(tmp),cha1[id]++,cha1[i]--,sum++;
			else cha2[id]++,cha2[i]--;
		}
	}
}

pair<int,int> dfs1(int id,int in_e){
	int sum1=cha1[id],sum2=cha2[id];
	for (int tmp:e[id]){
		if (in_e!=(tmp^1)) continue;
		pair<int,int> an=dfs1(v[tmp],tmp);
		sum1+=an.first;
		sum2+=an.second;
	}
	if (in_e!=0)
		if (sum==sum1 and !sum2)
			ans.push_back(in_e/2);
	return {sum1,sum2};
}

int main(){
	col[0]=1;
	scanf("%d %d",&n,&m);
	for (int i=1;i<=m;i++){
		int uu,vv;
		scanf("%d %d",&uu,&vv);
		u[++siz1]=uu,v[siz1]=vv;
		e[uu].push_back(siz1);
		u[++siz1]=vv,v[siz1]=uu;
		e[vv].push_back(siz1);
	}
	for (int i=1;i<=n;i++){
		if (!col[i])
			if (!is_two(i,0))
				notc.push_back(i);
	}
	if (notc.size()>1){ //第2点
		printf("0");
		return 0;
	}
	if (notc.empty()){ //第1点
		printf("%d\n",m);
		for (int i=1;i<=m;i++) printf("%d ",i);
		return 0;
	}
	int sta=notc[0];
	dfs(sta,0);
	if (badid.size()==1) ans.push_back(badid[0]/2); //第3.1.2点 //第3.1.1和3.1.3被省略了
	dfs1(sta,0); //第3.2.1点
	sort(ans.begin(),ans.end());
	printf("%d\n",ans.size());
	for (int i:ans) printf("%d ",i);

	return 0;
}

我的output:

0

答案:

6
312 990 1479 2729 6395 9950 
2025/1/13 21:19
加载中...