zoukankan      html  css  js  c++  java
  • [NOI2017]游戏

    Description:

    小 L 计划进行(n​)场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏。小 L 的赛车有三辆,分别用大写字母ABC表示。地图一共有四种,分别用小写字母x、a、b、c表示。其中,赛车A不适合在地图a上使用,赛车B不适合在地图b上使用,赛车C不适合在地图c上使用,而地图x则适合所有赛车参加。适合所有赛车参加的地图并不多见,最多只会有d张。(n​)场游戏的地图可以用一个小写字母组成的字符串描述。例如:S=xaabxcbc表示小 L 计划进行(8​)场游戏,其中第(1​)场和第(5​)场的地图类型是x,适合所有赛车,第(2​)场和第(3​)场的地图是a,不适合赛车A,第(4​)场和第(7​)场的地图是b,不适合赛车B,第(6​)场和第(8​)场的地图是c,不适合赛车C。小 L 对游戏有一些特殊的要求,这些要求可以用四元组 ((i, h_i, j, h_j)​)来描述,表示若在第(i​)场使用型号为(h_i​)的车子,则第(j​)场游戏要使用型号为(h_j​)的车子。你能帮小 L 选择每场游戏使用的赛车吗?如果有多种方案,输出任意一种方案。如果无解,输出 “-1’’(不含双引号)。

    Hint :

    (nle 10^5)

    Solution :

    考虑如果没有(x)地图,这就是个普通的(2-SAT)

    但连边还是有细节的:

    (i) 不适合 (h_i) 则直接忽视

    (i) 适合 (h_i)(j) 不适合 (h_j) ,则连边 (i->i^{'}) ,表示一定不能选 (h_i)

    其他的就是一般情况了

    现在加入(x)地图后变成了(3-SAT),为不可做的(NP)问题

    观察到 (x地图数量 le 8)

    考虑枚举那个地图是 (a) 还是 (b)

    (a) 则能走 (b)(c)

    (b) 则能走 (a)(c)

    这样便覆盖了所有情况

    复杂度 (O(2^8*(n+m))) 足已通过本题

    而这题还要求输出方案,那我们就按字典序连边和输出,注意要分类讨论

    #include <map>
    #include <set>
    #include <stack>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define ls p<<1 
    #define rs p<<1|1
    using namespace std;
    typedef long long ll;
    const int mxn=1e5+5;
    int n,m,d,k,cnt,tot,col;
    int x[mxn],y[mxn],hd[mxn],bl[mxn],pos[mxn],dfn[mxn],low[mxn],ins[mxn];
    char p[mxn],q[mxn],s[mxn],ans[mxn];
    stack<int > st;
    
    struct ed {
    	int to,nxt;
    }t[mxn<<1];
    
    inline void add(int u,int v) {
    	t[++cnt]=(ed) {v,hd[u]}; hd[u]=cnt;
    } 
    
    inline int read() {
    	char c=getchar(); int x=0,f=1;
    	while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
    	while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
    	return x*f;
    }
    inline void chkmax(int &x,int y) {if(x<y) x=y;}
    inline void chkmin(int &x,int y) {if(x>y) x=y;}
    
    void clr() {
    	memset(dfn,0,sizeof(dfn));
    	memset(low,0,sizeof(low));
    	memset(ins,0,sizeof(ins));
    	memset(bl,0,sizeof(bl));
    	memset(hd,0,sizeof(hd));
    	col=cnt=tot=0;
    }
    
    void tj(int u)
    {
    	dfn[u]=low[u]=++tot; ins[u]=1; st.push(u);
    	for(int i=hd[u];i;i=t[i].nxt) {
    		int v=t[i].to;
    		if(!dfn[v]) tj(v),chkmin(low[u],low[v]);
    		else if(ins[v]) chkmin(low[u],dfn[v]);
    	}
    	if(low[u]==dfn[u]) {
    		++col;
    		do {
    			bl[u]=col; u=st.top();
    			st.pop(); ins[u]=0;
    		} while(low[u]!=dfn[u]);
    	}
    }
    
    int check() {
    	for(int i=1;i<=2*n;++i) 
    		if(!dfn[i]) tj(i);
    	for(int i=1;i<=n;++i) {
    		if(bl[i]==bl[i+n]) return 0;
    		if(bl[i]<bl[i+n]) ans[i]=(s[i]=='A'?'B':'A');
    		else ans[i]=(s[i]=='C'?'B':'C');
    	}	
    	for(int i=1;i<=n;++i) printf("%c",ans[i]);
    	return 1;
    }
    
    void solve() 
    {
    	for(int i=0;i<(1<<d);++i) { //枚举x地图
    		clr();
    		for(int j=1;j<=d;++j) s[pos[j]]=((i>>(j-1))&1)?'A':'B';
    		for(int j=1;j<=m;++j) {
    			if(p[j]==s[x[j]]) continue ;
    			if(q[j]==s[y[j]]) {
    				if(p[j]=='C'||(p[j]=='B'&&s[x[j]]=='C')) add(x[j]+n,x[j]);
    				else add(x[j],x[j]+n);
    				continue ;
    			}	//特殊情况
    			int tag1=0,tag2=0;
    			if(p[j]=='C'||(p[j]=='B'&&s[x[j]]=='C')) tag1=n;
    			if(q[j]=='C'||(q[j]=='B'&&s[y[j]]=='C')) tag2=n;
    			add(x[j]+tag1,y[j]+tag2); add(y[j]-tag2+n,x[j]-tag1+n);
                //巧妙的分类讨论,避免了冗长的代码
    		}
    		if(check()) return ;
    	}
    	printf("-1"); 
    }
    
    int main()
    {
    	n=read(); d=read();
    	scanf("%s",s+1); m=read();
    	for(int i=1;i<=n;++i) {
    		if(s[i]=='x') pos[++k]=i;
    		s[i]-=32;
    	}
    	for(int i=1;i<=m;++i) scanf("%d %c %d %c",&x[i],&p[i],&y[i],&q[i]);
    	solve();
        return 0; 
    }
    
    
  • 相关阅读:
    通过Ajax的方式执行GP服务
    Arcgis for js之GP实现缓冲区计算
    sde用sql实现erase
    OL2中设置鼠标的样式
    OL2中重置地图DIV大小后地图的联动
    OL2中的多地图联动展示
    Codeforces Round #357 (Div. 2) Heap Operations
    POJ-1847 Tram
    【转】一些图论、网络流入门题总结、汇总
    POJ-2398 Toy Storage
  • 原文地址:https://www.cnblogs.com/list1/p/10470285.html
Copyright © 2011-2022 走看看