奇怪的问题,求条玄关
查看原帖
奇怪的问题,求条玄关
364070
Lord_c楼主2024/11/23 22:34
#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define ROF(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
const int N=3e5+40,T=3e5+10,F=3e5+20,U=3e5+30;
int fa[N],ww[N],n,m,visp[N],vis[N];
struct node{
	int to,nxt;int w;
}edge[N<<1];
int head[N],tot;
void add(int x,int y,int z) {
	edge[++tot].to=y;edge[tot].w=z;edge[tot].nxt=head[x];head[x]=tot;
}
void INIT() {
	tot=1;
	memset(head,0,sizeof(head));
	memset(vis,-1,sizeof(vis));
	memset(visp,0,sizeof(visp));
	FOR(i,1,N-1)fa[i]=i,ww[i]=0;
}
int dfs_c(int x) {
	visp[x]=1;int ret=((x!=T)&&(x!=F)&&(x!=U));
	for(int i=head[x];i;i=edge[i].nxt){
		int v=edge[i].to;if(visp[v])continue;
		ret+=dfs_c(v);
	}
	return ret;
}
int dfs(int x,int fa,int val) {
	if(vis[x]==-1) {
		vis[x]=val;
	} else {
		if(vis[x]!=val)return true;
		return false;
	}
	for(int i=head[x];i;i=edge[i].nxt) {
		if(i==fa)continue;
		int v=edge[i].to,w=edge[i].w;
		if(dfs(v,i^1,val^w))return true;
	}
	return false;
}
int main(){
	int c,T;scanf("%d%d",&c,&T);
	while(T--) {
		scanf("%d%d",&n,&m);
		INIT();
		FOR(i,1,m) {
			char op[5];int x,y;
			scanf("%s%d",op,&x);int nm=op[0];
			if(nm=='+'||nm=='-') {
				scanf("%d",&y);
				if(nm=='+'){
					fa[x]=fa[y];ww[x]=ww[y];
				} else if(nm=='-') {
					fa[x]=fa[y];ww[x]=ww[y]^1;
				}
			} 
			else {
				ww[x]=0;
				if(nm=='T')fa[x]=T;
				if(nm=='F')fa[x]=F;
				if(nm=='U')fa[x]=U;
			}
		}
		FOR(i,1,n){
			add(i,fa[i],ww[i]);
			add(fa[i],i,ww[i]);
		}
		int cnt=dfs_c(U);//visp是标U的 
		FOR(i,1,n) {
			if(vis[i]==-1&&!visp[i]) {
				if(dfs(i,0,0)) {
					cnt+=dfs_c(i);
				}
			}
		}
		printf("%d\n",cnt);
	}
	return 0;
}

这个代码在统计相同的询问时,询问组数 T 不同会输出不同的解 例如第一个测试点中

1 2
10 10
+ 5 3
+ 4 3
U 3
- 1 7
- 2 9
+ 7 2
U 9
T 6
- 10 10
- 8 8

10 10
+ 9 8
- 8 2
+ 2 9
- 1 3
+ 3 4
+ 4 5
+ 5 6
- 6 7
- 7 10
+ 10 1

TT 输入 22 那么第一个询问的结果是 1010TT11 时则答案为 99

2024/11/23 22:34
加载中...