• 「NOI2017」游戏 解题报告


    「NOI2017」游戏

    (d)这么小,你考虑直接对(d)个东西暴力

    枚举(x)(a)(b)(c)就不用了,因为(a,b)已经包含(c))了,剩下的就是个(2-sat)问题了

    但是你发现有个情况是,在若(A)(B)时,如果(B)(ban)了,那么(A)也要被(ban)

    我们记录一下被(ban)的点,然后在球方案的时候判一下(不得不用topo排序了..

    但是其实也可以(A)(lnot A),就可以直接比较SCC编号大小搞方案了


    Code:

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <vector>
    #include <algorithm>
    using std::min;
    const int SIZE=1<<21;
    char ibuf[SIZE],*iS,*iT;
    //#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),iS==iT?EOF:*iS++):*iS++)
    #define gc() getchar()
    template <class T>
    void read(T &x)
    {
    	x=0;char c=gc();
    	while(!isdigit(c)) c=gc();
    	while(isdigit(c)) x=x*10+c-'0',c=gc();
    }
    template <class T>
    void reads(T &x)
    {
    	char c=gc();
    	while(c<'a'||c>'z') c=gc();
    	x=c-'a'+1;
    }
    template <class T>
    void readb(T &x)
    {
    	char c=gc();
    	while(c<'A'||c>'Z') c=gc();
    	x=c-'A'+1;
    }
    const int N=2e5+10;
    int head[N],to[N],Next[N],cnt;
    void add(int u,int v)
    {
    	to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
    }
    struct _toki
    {
    	int a,b,c,d;
    }toki[N];
    int n,m,_n,yuu[N][4],ops[N],saki[N];
    int val[N],ban[N],Ban[N],q[N],bel[N],opsi[N];
    int low[N],dfn[N],in[N],sta[N],tot,dfsclock;
    std::vector <int> E[N];
    void tarjan(int now)
    {
    	dfn[now]=low[now]=++dfsclock;
    	in[sta[++tot]=now]=1;
    	for(int v,i=head[now];i;i=Next[i])
    	{
    		if(!dfn[v=to[i]])
    		{
    			tarjan(v);
    			low[now]=min(low[now],low[v]);
    		}
    		else if(in[v])
    			low[now]=min(low[now],dfn[v]);
    	}
    	if(low[now]==dfn[now])
    	{
    		int k;++_n;
    		do
    		{
    			k=sta[tot--];
    			in[k]=0;
    			bel[k]=_n;
    		}while(now!=k);
    	}
    }
    int solve()
    {
    	memset(head,0,sizeof head);cnt=0;
    	memset(ban,0,sizeof ban);
    	memset(Ban,0,sizeof Ban);
    	for(int a,b,c,d,i=1;i<=m;i++)
    	{
    		a=toki[i].a,b=toki[i].b,c=toki[i].c,d=toki[i].d;
    		if(saki[a]==b) continue;
    		if(saki[c]==d)
    		{
    			ban[yuu[a][b]]=1;
    			continue;
    		}
    		add(yuu[a][b],yuu[c][d]);
    		add(ops[yuu[c][d]],ops[yuu[a][b]]);
    	}
    	memset(in,0,sizeof in);
    	memset(dfn,0,sizeof dfn);
    	memset(low,0,sizeof low);
    	memset(bel,0,sizeof bel);
    	memset(opsi,0,sizeof opsi);
    	_n=dfsclock=0;
    	for(int i=1;i<=n<<1;i++)
    		if(!dfn[i])
    			tarjan(i);
    	for(int i=1;i<=n;i++)
    		if(bel[i]==bel[i+n])
    			return -1;
    	memset(val,-1,sizeof val);
    	for(int i=1;i<=_n;i++) E[i].clear();
    	//int ecnt=0;
    	for(int u=1;u<=n<<1;u++)
    	{
    		for(int v,i=head[u];i;i=Next[i])
    			if(bel[u]!=bel[v=to[i]])
    				E[bel[v]].push_back(bel[u]),++in[bel[u]];//++ecnt;
    		Ban[bel[u]]|=ban[u];
    		opsi[bel[u]]=bel[ops[u]];
    	}
    	int l=1,r=0;
    	for(int i=1;i<=_n;i++)
    		if(!in[i]&&!Ban[i])
    			q[++r]=i;
    	while(l<=r)
    	{
    		int now=q[l++];
    		if(val[now]==-1) val[now]=0,val[opsi[now]]=1;
    		for(int v,i=0;i<E[now].size();i++)
    		{
    			v=E[now][i];
    			--in[v];
    			if(!in[v]&&!Ban[v]) q[++r]=v;
    		}
    	}
    	for(int i=1;i<=n;i++)
    		if(val[bel[i]]==-1)
    			return -1;
    	for(int i=1;i<=n;i++)
    	{
    	    int x=val[bel[i]];
    		for(int j=1;j<=3;j++)
    		{
    			if(saki[i]!=j)
    			{
    				if(!x) putchar('A'+j-1);
    				--x;
    			}
    		}
    		//puts("");
    	}
    	return 0;
    }
    int main()
    {
        //freopen("game.in","r",stdin);
        //freopen("game.out","w",stdout);
        int d,yuy[10];
    	read(n),read(d);
    	d=0;
    	for(int i=1;i<=n;i++)
    	{
    	    ops[i]=i+n;
    		ops[i+n]=i;
    		reads(saki[i]);
    		if(saki[i]==24)
    		{
    			yuy[++d]=i;
    			continue;
    		}
    		int aya=i;
    		for(int j=1;j<=3;j++)
    		{
    			if(saki[i]!=j)
    			{
    				yuu[i][j]=aya;
    				aya+=n;
    			}
    		}
    	}
    	read(m);
    	for(int i=1;i<=m;i++) read(toki[i].a),readb(toki[i].b),read(toki[i].c),readb(toki[i].d);
    	if(!d)
    	{
    		if(solve()==-1) puts("-1");
    		return 0;
    	}
    	for(int s=0;s<1<<d;s++)
    	{
    		for(int i=1;i<=d;i++)
    		{
    			if(!(s>>i-1&1))
    			{
    				saki[yuy[i]]=1;
    				yuu[yuy[i]][2]=yuy[i];
    				yuu[yuy[i]][3]=yuy[i]+n;
    			}
    			else
    			{
    				yuu[yuy[i]][1]=yuy[i];
    				saki[yuy[i]]=2;
    				yuu[yuy[i]][3]=yuy[i]+n;
    			}
    		}
    		if(~solve()) return 0;
    	}
    	puts("-1");
    	return 0;
    }
    

    2019.6.2

  • 相关阅读:
    Casting
    hdu 1164 Eddy's research I
    hdu 1212 Big Number
    CF271 C. Secret
    hdu 1065 I Think I Need a Houseboat
    单档——状态码显示设置,状态码更改链表更新
    单身金额统计,更新显示到单头
    开窗设计器——条件,参数,返回值接收显示
    单档——单头内容新增、修改后同步更新到其他相关数据表
    TIPTOP之分割split函数方法、getIndexOf、subString、replace、临时表创建;
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10964110.html
Copyright © 2020-2023  润新知