关于NOIP T2
  • 板块学术版
  • 楼主AAA404
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/11/26 14:55
  • 上次更新2023/11/26 16:46:23
查看原帖
关于NOIP T2
723198
AAA404楼主2023/11/26 14:55

蒟蒻没去参加,今天自己打了一遍

T2思路是 2-SAT,但是挂了,只能过样例一二和自己造的小数据

洛谷上自测:30pts

f[i]f[i] 表示当前强连通分量是否需要 U ,如果需要必然是整个强连通分量都需要,故乘上 sizesize ,最后除以二是因为每个变量有两个对应节点

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,dfn[N<<1],low[N<<1],sta[N<<2],insta[N<<1],cnt,tot,c,t,sz[N<<1],top,id[N<<1],f[N<<1];
char val[N];
vector<int>v[N<<1],g[N<<1];
struct node{
	int op,num;
}p[N];
void tarjan(int u)
{
//	cout<<u<<endl;
	dfn[u]=low[u]=++cnt;
	sta[++top]=u,insta[u]=1;
	for(int t:v[u])
	{
		if(!dfn[t])
		{
			tarjan(t);
			low[u]=min(low[u],low[t]);
		} 
		else if(insta[t])low[u]=min(low[u],dfn[t]);
	}
	if(dfn[u]==low[u])
	{
		id[u]=++tot;
		sz[tot]=1;
//		cout<<u<<" ";
		while(sta[top]!=u)
		{
			int tmp=sta[top];
			id[tmp]=tot;
			insta[tmp]=0;
			sz[tot]++;
			top--;
//			cout<<tmp<<" ";
		}
		top--;
		insta[u]=0;
//		cout<<endl;
	}
	return;
}
void reset()
{
	for(int i=1;i<=tot;i++)sz[i]=0,g[i].clear(),f[i]=0;
	for(int i=1;i<=n*2;i++)v[i].clear(),dfn[i]=low[i]=0;
	for(int i=1;i<=n;i++)val[i]='\0',p[i].op=p[i].num=0;
	top=cnt=tot=0;
	return;
}
void add(int x,int y)
{
	v[x].push_back(y);
	return;
}
char rever(char ch)
{
	if(ch=='T')return 'F';
	if(ch=='F')return 'T';
	return ch;
}
int get1(int x)
{
	if(x>n)return x-n;
	return x;
}
void dfs(int now)
{
	for(int t:g[now])
	{
		f[t]=1;
		dfs(t);
	}
	return;
}
int main()
{
	clock_t c1=clock();
  	freopen("tribool.in","r",stdin);
  	freopen("tribool.out","w",stdout);
 	ios::sync_with_stdio(0);
 	cin.tie(0);cout.tie(0);
	cin>>c>>t;
	while(t--)
	{
		cin>>n>>m;
		int ans=0;
		for(int x=1;x<=m;x++)
		{
			char op;int i,j;
			cin>>op>>i;
			if(op=='-'||op=='+')cin>>j;
			if(op=='-')
			{
				p[i].op=-1,p[i].num=j;
				val[i]=rever(val[j]);
			}
			else if(op=='+')
			{
				p[i].op=1,p[i].num=j;
				val[i]=val[j];
			}
			else
			{
				val[i]=op;
				p[i].op=0;
			}
		}
		for(int i=1;i<=n;i++)
		{
			int op=p[i].op,j=p[i].num;
			if(op==1)
			{
				if(i==j)continue;
				if(val[j]=='T')
				{
					add(j,i);
				}
				else if(val[j]=='F')
				{
					add(j+n,i+n);
				}
				else
				{
					//jT->iT
					add(j,i);
					//jF->iF
					add(j+n,i+n);
				}
			}
			else
			{
				if(op==0)continue;
				if(val[j]=='T')
				{
					add(j,i+n);
				}
				else if(val[j]=='F')
				{
					add(j+n,i);
				}
				else
				{
					//jT->iF
					add(j,i+n);
					//jF->iT
					add(j+n,i);
				}
			}
		}
		for(int i=1;i<=n;i++)
		if(val[i]=='U')
		{
			add(i,i+n),add(i+n,i);
//			dfs(i);
		}
		for(int i=1;i<=n*2;i++)
		if(!dfn[i])tarjan(i);
		for(int i=1;i<=n;i++)
		{
			if(id[i]==id[i+n])
			{
				f[id[i]]=1;
			}
		}
		for(int i=1;i<=n*2;i++)
		for(int t:v[i])
			{
				if(id[t]!=id[i])
				{
					g[id[i]].push_back(id[t]);
				}
			}
		for(int i=1;i<=tot;i++)
		{
			if(f[i])
			dfs(i);
		}
		for(int i=1;i<=tot;i++)
		ans+=f[i]*sz[i];
		cout<<ans/2<<endl;
		reset();
	}
#ifdef LOCAL
	cerr<<"Time used:"<<clock()-c1<<"ms"<<endl;
#endif
	return 0;
}

2023/11/26 14:55
加载中...