首页 > 其他分享 >P3825 [NOI2017] 游戏

P3825 [NOI2017] 游戏

时间:2024-07-11 10:59:07浏览次数:9  
标签:lmy 游戏 lyymcl ll NOI2017 MAXN 赛车 P3825 sta

题目大意

有四种类型的比赛 \(x,a,b,c\),三种赛车(\(A,B,C\))。其中 \(x\) 的数量 为 \(d\)。

\(x\) 表示三种赛车都可以选, \(a\) 表示 \(A\) 种不能选,\(b\) 表示 \(B\) 种不能选,\(c\) 表示 \(C\) 种不能选。

现在要比 \(n\) 场,有 \(m\) 个限制形如:

\(p,f,q,t\) 表示如果第 \(p\) 场选了第 \(f\) 种的赛车则第 \(q\) 场必须选用第 \(t\) 种赛车。

任意一组满足所有要求的赛车选择方案。

\(n,m\leq10^5\),\(d\leq8\)。

思路

如果没有 \(x\) 的话可以直接考虑 \(2-SAT\),以每一场比赛作为变量,能选的两种赛车作为布尔变量即可,然后就是找规律。将变量设为 \(i_0\) 和 \(i_1\)。

但是现在处理 \(x\),注意到数量很少,所以可以直接枚举 \(x\) 的种类,将它变成 \(a\) 或 \(b\)。

为什么我们不需要再变成 \(c\) 呢?因为在发现如果要不选 \(C\) 的话在 \(a,b\) 中都可以直接不选(如果这样是对的话),所以重复了,直接不选。这样我们可以大概猜的最终时间复杂度是 \(O(2^d(m+n))\)。

考虑建图。分三种情况,设第 \(i\) 个比赛目前不能选 \(F_i\):

  1. \(f_p=F_p\),则这个情况一定不会成立,可以直接忽略
  2. \(t_q=F_q\),则这个情况的前提一定不能成立,连 \(p_0\rightarrow p_1\)。
  3. 除此以外的情况,连命题 \(p_0\rightarrow q_0\) 与它的逆否命题 \(q_1\rightarrow p_1\)。

之后跑 \(2-SAT\) 求是否合法与输出方案数即可。对于 \(2-SAT\) 方案数,我们理应按照缩点后图跑拓扑排序后优先输出拓扑序大的,但因为 \(Tarjan\) 缩点就是按拓扑排序的逆序输出的,所以我们只需要输出强连通分量编号小的即可。

代码

#include<bits/stdc++.h>
#define T(u,v) u+turn[rc[u]][v]
#define N(u,v) u+turn2[rc[u]][v]
using namespace std;
typedef long long ll;
const ll MAXN=1e5+5;
ll n,d,m;
vector<ll>adj[MAXN];
ll lyymcl[MAXN],dfn[MAXN],yjr[MAXN],tot;
ll id[MAXN],scc;
bool ins[MAXN];
void add(ll u,ll v){
	adj[u].push_back(v);
}
stack<ll>sta;
ll turn[3][3],turn2[3][3];
ll rc[MAXN];
void lycnpy(ll u){
	dfn[u]=lyymcl[u]=++tot;
	ins[u]=true;
	sta.push(u);
	for(auto lmy:adj[u]){
		if(!dfn[lmy]){
			lycnpy(lmy);
			lyymcl[u]=min(lyymcl[u],lyymcl[lmy]);
		}else if(ins[lmy]){
			lyymcl[u]=min(lyymcl[u],dfn[lmy]);
		}
	}
	if(lyymcl[u]==dfn[u]){
		++scc;
		while(sta.top()!=u){
			id[sta.top()]=scc;
			ins[sta.top()]=false;
			sta.pop();
		}
		id[u]=scc;
		ins[u]=false;
		sta.pop();
	}
}
void lyc(){
	for(int i=1;i<=2*n;++i){
		if(!dfn[i]){
			lycnpy(i);
		}
	}
}
struct Query{
	ll p,q;
	ll t,f;
}ask[MAXN];
void clear(){
	for(int i=0;i<=2*n+3;++i){
		adj[i].clear();
	}
	memset(lyymcl,0,sizeof(lyymcl));
	memset(dfn,0,sizeof(dfn));
	memset(yjr,0,sizeof(yjr));
	tot=scc=0;
	memset(id,0,sizeof(id));
} 
ll tn(char c){
	if(c=='a'||c=='A'){
		return 0;
	} 
	if(c=='b'||c=='B'){
		return 1;
	}
	if(c=='c'||c=='C'){
		return 2;
	}
	return 4;
}
void check(){
		clear();
		for(int i=1;i<=m;++i){
			ll t=ask[i].t,f=ask[i].f,p=ask[i].p,q=ask[i].q;
			if(f==rc[p]){
				continue;
			}
			if(t==rc[q]){
				add(T(p,f),N(p,f));
			}else{
				add(T(p,f),T(q,t));
				add(N(q,t),N(p,f));
			}
		}
		lyc();
		bool good=false;
		for(int i=1;i<=n;++i){
			if(id[i]==id[n+i]){
				good=true;
				break;
			}
		}
		if(!good){
			for(int i=1;i<=n;++i){
				if(id[i]<id[n+i]){
					if(rc[i]==0){
						cout<<"B";
					}else if(rc[i]==1){
						cout<<"A";
					}else{
						cout<<"A";
					}
				}else{
					if(rc[i]==0){
						cout<<"C";
					}else if(rc[i]==1){
						cout<<"C";
					}else{
						cout<<"B";
					}
				}
			}
			exit(0);
		}
}
void dfs(ll x){
	if(x==n+1){
		check();
		return;
	}
	if(rc[x]==4){
		rc[x]=0;
		dfs(x+1);
		rc[x]=1;
		dfs(x+1);
		return;
	}
	dfs(x+1);
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin>>n>>d;
	for(int i=1;i<=n;++i){
		char c;
		cin>>c;
		rc[i]=tn(c);
	}
	for(int i=0;i<3;++i){
		bool good=false;
		for(int j=0;j<3;++j){
			if(j==i){
				continue;
			}
			if(good){
				turn[i][j]=n;
				turn2[i][j]=0;
			}else{
				good=true;
				turn[i][j]=0;
				turn2[i][j]=n;
			}
		}
	}
	cin>>m;
	for(int i=1;i<=m;++i){
		char f,t;
		cin>>ask[i].p>>f>>ask[i].q>>t;
		ask[i].f=tn(f);
		ask[i].t=tn(t);
	}
	dfs(1);
	cout<<-1<<endl;
	return 0;
}

标签:lmy,游戏,lyymcl,ll,NOI2017,MAXN,赛车,P3825,sta
From: https://www.cnblogs.com/tanghg/p/18295609/solution-p3825

相关文章

  • 撸包小游戏对接广告联盟APP系统开发源码搭建
    “撸包小游戏广告联盟APP”源码搭建涉及多个关键步骤,以下是一个简化的流程:市场调研与需求分析:对市场进行深入调研,了解目标用户群体和他们的需求。分析竞争对手的小游戏和广告策略,确定自己小游戏的特色和定位。游戏开发:根据市场调研的结果,设计并开发具有吸引力的撸包小......
  • Java面向对象小游戏--文字版格斗游戏(附带全套源代码)->基于JavaBean
    一、前言java部分的基础学习已经完结,接下来给大家分享的大多为java相关的案例分析,也会有一些小项目,这点不要太过于担心,主要还是基础部分要打牢固。java部分的难点就在面向对象这一点,学习C语言的小伙伴们应该是第一次听说方法。这点也是和C语言相差巨大的地方,不过对于学习过pyt......
  • Android自定义View游戏方向轮盘转向盘方向盘
    在画之前做一些规划,把View分成6份:一份就是小圆的半径,两份就是大圆的半径,大圆的圆心始终是中心,小圆位置根据手指变化,当我们手指超出大圆的范围时候就把他固定在大圆的边缘上(利用相似三角形来计算位置)。privatevoidcomputePosition(floatx,floaty){float......
  • 使用Godot4组件制作竖版太空射击游戏_2D卷轴飞机射击-碰撞框和受伤区域(六)
    文章目录开发思路受击区域设置碰撞层使用Godot4组件制作竖版太空射击游戏_2D卷轴飞机射击(一)使用Godot4组件制作竖版太空射击游戏_2D卷轴飞机射击-激光组件(二)使用Godot4组件制作竖版太空射击游戏_2D卷轴飞机射击-飞船动画(三)使用Godot4组件制作竖版太空射击游戏_2D卷......
  • 开启新纪元!被AI驱动的游戏世界,提升游戏体验
     随着人工智能的高速发展,人工智能逐渐应用到了生活中的方方面面,人工智能在游戏中也有诸多应用,在游戏里领域扮演了相当重要的角色。游戏AI是伴随着电子游戏而出现的,在早期的游戏中就出现了对抗类AI角色,后来逐渐出现了更复杂的NPCAI,除通常理解的游戏AI之外,语音、视觉、机器学习......
  • html+css+js贪吃蛇游戏
    贪吃蛇游戏......
  • 【宠物消消乐】休闲小游戏 软件 游戏
    这是一款宠物消消乐休闲小游戏,是一款超好玩的三消游戏,画面精美、上手简单、休闲有趣、是最开始玩的最多的,因为休闲游戏这类的比较多,而且比较容易打发时间,而且玩法也有趣,一关关的也很容易过,过不了就一直想玩下去。1、主要玩法:1)玩家进入游戏需要先购买体力,每天可购买......
  • 小学期数据结构——消球游戏
    消球游戏设计一个程序实现消球游戏:在棋盘内,一开始随机初始化三个不同色小球,一次可移动一个小球至空白位置,当同色5个小球连成直线,横、竖、对角均可,则小球消除并得分。消除1个小球得1分,当小球移动1次没有消除时,系统会自动随机产生三个小球。基本要求:(1)要求实现图形化界面,可......
  • 苹果笔记本能玩网页游戏吗 苹果电脑玩steam游戏怎么样 苹果手机可以玩游戏吗 mac电脑
    苹果笔记本无疑是优秀的“办公助手”,但对于游戏爱好者来说,它的游戏性能如何?首先,我们来讨论苹果笔记本在玩网页游戏方面的表现。一、苹果笔记本能玩网页游戏吗苹果笔记本历代都配备了高分辨率的屏幕和优质的显示技术,这使得苹果笔记本相比于Windows电脑,在视觉体验上有着明显的......
  • Mac电脑上有什么好玩的肉鸽游戏推荐 苹果电脑怎么玩以撒的结合
    Mac电脑尽管在游戏兼容性上可能不及Windows。但是,对于喜欢在Mac上游玩的玩家来说,依然有不少优秀的游戏可以选择,尤其是那些富有挑战性和策略性的肉鸽游戏。此外,对于经典游戏《以撒的结合》,Mac平台也提供了良好的游戏体验。一、Mac电脑上有什么好玩的肉鸽游戏肉鸽游戏是Rogueli......