zoukankan      html  css  js  c++  java
  • loj#2305. 「NOI2017」游戏 2-sat

    链接

    https://loj.ac/problem/2305
    https://www.luogu.org/problemnew/show/P3825

    思路

    3-sat神马的就不要想了,NP问题
    除去x每个点只有两种可能,2-sat
    x只有8个,(3^n)暴力枚举哪个不选
    2-sat是对称性的
    当起点x的战车不存在,continue
    else 当终点的战车不存在,那么起点战车也不能选呀(选了就G了呀),起点连向剩下的那个可选点
    else 起点终点都还在,连起来,否逆命题:原命题为:若a,则b。逆否命题为:若非b,则非a。
    所以他俩的兄弟还要连一条边
    但是计算一下发现,有点小超时呀
    其实只要枚举A和B(随便两个)就好了
    因为一个点最终只会用一辆车呀(有一辆就是个摆设)
    (2^n)已经把所有可以选的情况整出来了
    然后开心的(O(2^n(n+m)))

    其他的

    难道我天生就是制造bug的吗


    后记:
    uojTLE1个(貌似要随机化,输出,不管了)
    luoguwrong1个(spj没判回车)
    bzojok
    lojok

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=3e5+7;
    int read() {
    	int x=0,f=1;char s=getchar();
    	for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    	for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    	return x*f;
    }
    int n,m,d,head[N<<2],tot;
    int top,cnt,stak[N],low[N],dfn[N],belong[N];
    bool vis[N],Choose[N];
    char s[N],S[N];
    struct node {
    	int v,nxt;
    }e[N<<2];
    struct edge {
    	int i,x,j,y;
    }ABC[N];
    void add(int u,int v) {
    	swap(u,v);
    	e[++tot].v=v;
    	e[tot].nxt=head[u];
    	head[u]=tot;
    }
    void tarjan(int u) {
    	low[u]=dfn[u]=++cnt;
    	stak[++top]=u;
    	vis[u]=1;
    	for(int i=head[u];i;i=e[i].nxt) {
    		int v=e[i].v;
    		if(!dfn[v]) {
    			tarjan(v);
    			low[u]=min(low[u],low[v]);
    		} else if(vis[v]) {
    			low[u]=min(low[u],dfn[v]);
    		}
    	}
    	if(low[u]==dfn[u]) {
    		++belong[0];
    		while(stak[top]!=u) {
    			vis[stak[top]]=0;
    			belong[stak[top]]=belong[0];
    			top--;
    		} top--;
    		vis[u]=0;
    		belong[u]=belong[0];
    	}
    }
    void Clear() {
    	memset(head,0,sizeof(head));
        memset(low,0,sizeof(low));
        memset(dfn,0,sizeof(dfn));
        memset(vis,0,sizeof(vis));
        memset(belong,0,sizeof(belong));
    	cnt=top=tot=belong[0]=0;
    }
    int mmp[5][2]={ {1,2},
    			    {0,2},
    			 	{0,1},};
    void solve() {
    	int js=1;
    	for(int i=1;i<=n;++i) {
    		if(s[i]=='x'-'a') {
    			if(Choose[js]==0) S[i]=0;
    			else S[i]=1;
    		} else S[i]=s[i];
    	}
        for(int i=1;i<=m;++i) {
        	if(ABC[i].x==S[ABC[i].i]) continue;
        	int tmp_1= (mmp[S[ABC[i].i]][1]==ABC[i].x) ? mmp[S[ABC[i].i]][0] : mmp[S[ABC[i].i]][1];
    		int tmp_2= (mmp[S[ABC[i].j]][1]==ABC[i].y) ? mmp[S[ABC[i].j]][0] : mmp[S[ABC[i].j]][1];
        	if(ABC[i].y==S[ABC[i].j]) add(ABC[i].i+n*ABC[i].x,ABC[i].i+n*tmp_1);
    		else {
    			add(ABC[i].i+n*ABC[i].x,ABC[i].j+n*ABC[i].y);
    			add(ABC[i].j+n*tmp_2,ABC[i].i+n*tmp_1);
    		}
        }
        for(int i=1;i<=3*n;++i) {
        	// if(S[(i-1)/3+1]==(i+2)%3) continue;一定没有这一句
        	if(!dfn[i])
    			tarjan(i);
    	}
    	for(int i=1;i<=n;++i) {
    		if(belong[i+n*(mmp[S[i]][0])]==belong[i+n*(mmp[S[i]][1])]) return;
    		// if(S[i]=='a'&&belong[i+n]==belong[i+2*n]) return;
    		// if(S[i]=='b'&&belong[i]==belong[i+2*n]) return;
    		// if(S[i]=='c'&&belong[i]==belong[i+n]) return;
    	}
    	for(int i=1;i<=n;++i) {
    		if(S[i]==0) {
    			if(belong[i+n]>belong[i+2*n]) printf("B");
    			else printf("C");
    		}
    		if(S[i]==1) {
    			if(belong[i]>belong[i+2*n]) printf("A");
    			else printf("C");
    		}
    		if(S[i]==2) {
    			if(belong[i]>belong[i+n]) printf("A");
    			else printf("B");
    		}
    	}
    	exit(0);
    }
    int main() {
    //	freopen("a.in","r",stdin);
    	n=read(),d=read();
    	for(int i=1;i<=n;++i) {
    		char dd;
    		scanf("%c",&dd);
    		s[i]=dd-'a';
    	}
    	m=read();
    	for(int i=1;i<=m;++i) {
    		char s;
    		ABC[i].i=read();
    		s=getchar();
    		while(s==' ') s=getchar();
    		ABC[i].x= (s=='A') ? 0 : (s=='B') ? 1 : 2;
    		ABC[i].j=read();
    		s=getchar();
    		while(s==' ') s=getchar();
    		ABC[i].y= (s=='A') ? 0 : (s=='B') ? 1 : 2;
    		//end
    	}
    	for(int i=0;i<(1<<d);++i) {
    		for(int j=0;j<d;++j) Choose[j+1]=(bool)(1<<j)&i;
    		Clear();
    		solve();
    	}
    	puts("-1");
    	return 0;
    }
    
    
  • 相关阅读:
    Tinkoff Internship Warmup Round 2018 and Codeforces Round #475 (Div. 1) 963B 964D B Destruction of a Tree
    Educational Codeforces Round 40 (Rated for Div. 2) 954G G. Castle Defense
    Codeforces Round #470 (rated, Div. 1, based on VK Cup 2018 Round 1) 923D 947D 948E D. Picking Strings
    Codeforces Round #469 (Div. 1) 949C C. Data Center Maintenance (Div. 2 950E)
    Educational Codeforces Round 39 (Rated for Div. 2) 946E E. Largest Beautiful Number
    Educational Codeforces Round 37 (Rated for Div. 2) 920E E. Connected Components?
    Codeforces Round #456 (Div. 2) 912E E. Prime Gift
    Codeforces Round #456 (Div. 2) 912D D. Fishes
    D. An overnight dance in discotheque(Round4 418)
    i am back
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/10410247.html
Copyright © 2011-2022 走看看