zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    MapBox TileMill
    优秀电影
    Mapnik 编译安装过程
    Debian 入门安装与配置2
    学习opengl十大网站(转载)
    PostgresSQL 学习资料记录处
    c++模板编程-异质链表
    Linux-统一事件源
    三组I/O复用模型的比较
    ZigZag-LeetCode
  • 原文地址:https://www.cnblogs.com/nofind/p/12204133.html
Copyright © 2011-2022 走看看