刚学 OI 1ms,为什么这样做会产生环?
查看原帖
刚学 OI 1ms,为什么这样做会产生环?
563958
dxrS楼主2024/10/23 20:15

做法大概就是只关心来自哪个初始值。

个人认为这样只会产生自环,实则不然。

考场代码写得比较屎山。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int c,T,n,m,from[N],fa[N],siz[N],tot;
char op[N];
vector<pair<int,char> > G[N];
vector<pair<int,int> > g;
void dfs(int u){
	for(auto H:G[u]){
		int v=H.first;
		char c=H.second;
		if(c=='+') op[v]=op[u];
		else if(op[u]=='T') op[v]='F';
		else if(op[u]=='F') op[v]='T';
		else op[v]='U';
		from[v]=-1;
		dfs(v);
	}
}
inline void make(int n){ for(int i=1;i<=n;++i) fa[i]=i; }
int find(int x){ return fa[x]=(fa[x]==x?x:find(fa[x])); }
void merge(int u,int v){
	int a=find(u),b=find(v);
	if(a==b) return;
	if(siz[a]<siz[b]) fa[a]=b,siz[b]+=siz[a];
	else fa[b]=a,siz[a]+=siz[b];
}
void init(int u,int t,int flg){
	if(u==t&&~flg) return;
	++tot;
	for(auto H:G[u]){
		int v=H.first;
		char c=H.second;
		if(c=='+') op[v]=op[u];
		else if(op[u]=='+') op[v]='-';
		else op[v]='+';
		from[v]=from[u];
		init(v,t,1);
	}
}
inline int read(){
	int res=0;
	char ch=getchar();
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9') res=(res<<1)+(res<<3)+(ch^'0'),ch=getchar();
	return res;
}
void write(int x){
	if(x>=10) write(x/10);
	putchar((x%10)^'0');
}
int main(){
	c=read(),T=read();
	while(T--){
		n=read(),m=read();
		for(int i=1;i<=n;++i) from[i]=i,op[i]='?',G[i].clear(),G[i].shrink_to_fit();
		g.clear(),g.shrink_to_fit();
		while(m--){
			char OP=getchar();
			while(OP!='+'&&OP!='-'&&OP!='T'&&OP!='F'&&OP!='U') OP=getchar();
			if(OP=='+'){
				int i=read(),j=read();
				if(op[j]=='?') op[i]='+',from[i]=from[j];
				else if(op[j]=='+'||op[j]=='-') op[i]=op[j],from[i]=from[j];
				else op[i]=op[j],from[i]=-1;
			} else if(OP=='-'){
				int i=read(),j=read();
				if(op[j]=='?') op[i]='-',from[i]=j;
				else if(op[j]=='+') op[i]='-',from[i]=from[j];
				else if(op[j]=='-') op[i]='+',from[i]=from[j];
				else if(op[j]=='T') op[i]='F',from[i]=-1;
				else if(op[j]=='F') op[i]='T',from[i]=-1;
				else op[i]='U',from[i]=-1;
			} else{
				int i=read();
				op[i]=OP,from[i]=-1;
			}
		}	 
		for(int i=1;i<=n;++i) if(from[i]==i&&op[i]=='-') op[i]='U',from[i]=-1;
		for(int i=1;i<=n;++i) if(~from[i]) G[from[i]].push_back(make_pair(i,op[i]));
		for(int i=1;i<=n;++i) if(op[i]=='T'||op[i]=='F'||op[i]=='U') dfs(i);
		int cnt=0;
		for(int i=1;i<=n;++i) cnt+=(op[i]=='U');
		make(n);
		for(int i=1;i<=n;++i) if(~from[i]){
			if(find(from[i])==find(i)) g.push_back(make_pair(i,from[i]));
			else merge(from[i],i);
		}
		for(auto p:g){
			tot=0;
			init(p.first,p.first,-1);
			if(from[p.second]==p.second&&op[p.second]=='-') op[p.second]='U',from[p.second]=-1,cnt+=tot;
		}
		write(cnt),putchar('\n');
	}
	return 0;
}
2024/10/23 20:15
加载中...