P3825 [NOI2017]游戏

题意

先不考虑没有(d)的限制,此时每场比赛只有两种选择,这是一个典型的(2-SAT)模型。

发现(d)很小,自然想到枚举每个(x)用哪种车,但是(3^dm)显然是过不了的。于是我们枚举这个(x)不能用那种车,此时我们只需要枚举两个即可,因为此时三种车(ABC)都被放到(x)上判断过了。

code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int maxm=1e5+10;
const int maxd=10;
int n,m,cnt_edge,K,tim,scc,top;
int head[maxn],dfn[maxn],low[maxn],col[maxn],sta[maxn],a1[maxm],a2[maxm];
bool state[maxd],vis[maxn];
char s[maxn],t[maxn],b1[maxm],b2[maxm];
vector<int>a;
struct edge{int to,nxt;}e[maxm<<1];
inline int change1(int pos,char x)
{
	if(t[pos]=='a')return x=='C';
	if(t[pos]=='b')return x=='C';
	if(t[pos]=='c')return x=='B';
	return 2333;
}
inline char change2(int pos,int x)
{
	if(t[pos]=='a')return x?'C':'B';
	if(t[pos]=='b')return x?'C':'A';
	if(t[pos]=='c')return x?'B':'A';
	return 'd';
}
inline void add_edge(int u,int v)
{
	e[++cnt_edge].nxt=head[u];
	head[u]=cnt_edge;
	e[cnt_edge].to=v;
}
void tarjan(int x)
{
	dfn[x]=low[x]=++tim;
	sta[++top]=x;vis[x]=1;
	for(int i=head[x];i;i=e[i].nxt)
	{
		int y=e[i].to;
		if(!dfn[y])tarjan(y),low[x]=min(low[x],low[y]);
		else if(vis[y])low[x]=min(low[x],dfn[y]);
	}
	if(dfn[x]==low[x])
	{
		int y;scc++;
		do
		{
			y=sta[top--];
			col[y]=scc;vis[y]=0;
		}while(y!=x);
	}
}
inline void clear()
{
	memset(head,0,sizeof(head));
	memset(dfn,0,sizeof(dfn));
	memset(col,0,sizeof(col));
	cnt_edge=scc=top=tim=0;
	for(int i=1;i<=n;i++)t[i]=s[i];
}
inline bool check()
{
	clear();
	for(int i=1;i<=K;i++)t[a[i-1]]=state[i]?'c':'a';
	for(int i=1;i<=m;i++)
	{
		int x=a1[i],y=a2[i];char op1=b1[i],op2=b2[i];
		if(t[x]-'a'==op1-'A')continue;
		if(t[y]-'a'==op2-'A'){add_edge(2*x+change1(x,op1),2*x+(change1(x,op1)^1));continue;}
		add_edge(2*x+change1(x,op1),2*y+change1(y,op2));		
		add_edge(2*y+(change1(y,op2)^1),2*x+(change1(x,op1)^1));
	}
	for(int i=1;i<=n;i++)
	{
		if(!dfn[2*i])tarjan(2*i);
		if(!dfn[2*i+1])tarjan(2*i+1);
	}
	for(int i=1;i<=n;i++)if(col[2*i]==col[2*i+1])return 0;
	return 1;
}
bool dfs(int dep)
{
	if(dep==K+1)return check();
	state[dep]=0;
	if(dfs(dep+1))return 1;
	state[dep]=1;
	if(dfs(dep+1))return 1;
	return 0;
}
int main()
{
	scanf("%d%d",&n,&K);
	scanf("%s",s+1);
	for(int i=1;i<=n;i++)if(s[i]=='x')a.push_back(i);
	scanf("%d",&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&a1[i]);
		b1[i]=getchar();
		while(b1[i]!='A'&&b1[i]!='B'&&b1[i]!='C')b1[i]=getchar();
		scanf("%d",&a2[i]);
		b2[i]=getchar();
		while(b2[i]!='A'&&b2[i]!='B'&&b2[i]!='C')b2[i]=getchar();
	}
	if(!dfs(1)){puts("-1");return 0;}
	for(int i=1;i<=n;i++)putchar(change2(i,col[2*i]>col[2*i+1]));
	return 0;
}
原文地址:https://www.cnblogs.com/nofind/p/12204133.html