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;
}
标签:10,const,游戏,int,枚举,NOI2017,maxn,maxm,P3825 来源: https://www.cnblogs.com/nofind/p/12204133.html