【BZOJ4945&&UOJ317】游戏(2-sat,拓扑序)
题意:

思路:

输出方案时有一个优秀的性质可以利用:
tarjan缩点之后点所属的分量编号是原图的反的拓扑序
所以只需要在两种方案内找到所属分量编号较小的那个就行了,用来满足(i,i')那个限制
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
#define fi first
#define se second
#define MP make_pair
#define N 310000
#define M 410000
#define eps 1e-8
#define pi acos(-1)
#define oo 1e9 int head[M],vet[M],nxt[M],flag[M],dfn[M],low[M],belong[M],stk[M],
c[M],x[M],y[M],f[M][],num[M][],q[M],b[M],a[M],
n,m,D,tot,top,ans,tim,s,id;
char ch[M]; void add(int a,int b)
{
nxt[++tot]=head[a];
vet[tot]=b;
head[a]=tot;
} void tarjan(int u)
{
flag[u]=;
stk[++top]=u;
dfn[u]=low[u]=++tim;
int e=head[u];
while(e)
{
int v=vet[e];
if(!flag[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!belong[v]) low[u]=min(low[u],low[v]);
e=nxt[e];
}
if(dfn[u]==low[u])
{
belong[u]=++id;
while(top&&stk[top]!=u)
{
belong[stk[top]]=id;
stk[top--]=;
}
stk[top--]=;
}
} int solve()
{ for(int i=;i<=s;i++) flag[i]=low[i]=dfn[i]=head[i]=belong[i]=;
tot=;
for(int i=;i<=m;i++)
if(c[x[i]]!=f[i][])
{
if(c[y[i]]==f[i][])
{
int t1=num[x[i]][f[i][]];
int t2=num[x[i]][-f[i][]-c[x[i]]];
add(t1,t2);
}
else
{
int t1=num[x[i]][f[i][]];
int t2=num[y[i]][f[i][]];
add(t1,t2);
t1=num[y[i]][-c[y[i]]-f[i][]];
t2=num[x[i]][-c[x[i]]-f[i][]];
add(t1,t2); }
} top=tim=id=; for(int i=;i<=s;i++)
if(!flag[i]) tarjan(i); for(int i=;i<=n;i++)
{
int x,y;
if(c[i]==){x=; y=;}
if(c[i]==){x=; y=;}
if(c[i]==){x=; y=;}
if(belong[num[i][x]]==belong[num[i][y]]) return ;
} for(int i=;i<=n;i++)
{
int x,y;
if(c[i]==){x=; y=;}
if(c[i]==){x=; y=;}
if(c[i]==){x=; y=;}
int t;
if(belong[num[i][x]]<belong[num[i][y]]) t=x;
else t=y;
printf("%c",'A'+t-);
}
return ;
} void dfs(int k)
{
if(ans) return;
if(k==D+)
{
if(solve()) ans=;
return;
} for(int i=;i<=;i++)
{
c[b[k]]=i;
dfs(k+);
c[b[k]]=;
}
} int main()
{ scanf("%d%d",&n,&D);
scanf("%s",ch+);
for(int i=;i<=n;i++)
{
if(ch[i]=='x') a[i]=;
else a[i]=ch[i]-'a'+;
}
D=;
for(int i=;i<=n;i++)
if(a[i]==) b[++D]=i;
for(int i=;i<=n;i++) c[i]=a[i]; s=;
for(int i=;i<=n;i++)
for(int j=;j<=;j++) num[i][j]=++s; scanf("%d",&m);
char c1[];
char c2[];
for(int i=;i<=m;i++)
{
scanf("%d%s%d%s",&x[i],&c1,&y[i],&c2);
f[i][]=c1[]-'A'+;
f[i][]=c2[]-'A'+; }
ans=;
dfs();
if(!ans) printf("-1\n");
return ;
}
【BZOJ4945&&UOJ317】游戏(2-sat,拓扑序)的更多相关文章
- 【BZOJ-3832】Rally 拓扑序 + 线段树 (神思路题!)
3832: [Poi2014]Rally Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 168 Solved: ...
- BZOJ-4010 菜肴制作 贪心+堆+(拓扑图拓扑序)
无意做到...char哥还中途强势插入干我...然后据他所言,看了一会题,一转头,我爆了正解....可怕 4010: [HNOI2015]菜肴制作 Time Limit: 5 Sec Memory L ...
- hdu5438(2015长春赛区网络赛1002)拓扑序+DFS
题意:给出一张无向图,每个节点有各自的权值,问在点数为奇数的圈中的点的权值总和是多少. 通过拓扑序的做法标记出所有非圈上的点,做法就是加每条边的时候将两点的入度都加一,然后将所有度数为1的点入队,删去 ...
- poj3553 拓扑序+排序贪心
题意:有多个任务,每个任务有需要花费的时间和最后期限,任务之间也有一些先后关系,必须先完成某个才能开始某个,对于每个任务,如果没有越期,则超时为0,否则超时为结束时间-最后期限,求总超时时间最小的任务 ...
- poj2762 强连通+拓扑序
题意:有 n 个房间,不同房间之间有单向通道,问是否任意两个房间 A .B 都可以从 A 到 B 或从 B 到 A(有一条有就可以). 在这题中,如果一些点是在同一个强连通分量中,那么这些点肯定能够相 ...
- poj1420 拓扑序
题意:给出一个表格,一部分单元格是给定的数字,而另一部分单元格则是一个式子,表示是其他一些单元格的和,让你输出最后计算出的所有格子的数. 因为有些格子需要其他格子先计算出来,所以计算顺序是按照拓扑序的 ...
- poj1270 拓扑序(DFS)
题意:给出将会出现的多个字母,并紧接着给出一部分字母的大小关系,要求按照字典序从小到大输出所有符合上述关系的排列. 拓扑序,由于需要输出所有排列,所以需要使用 dfs ,只要点从小到大遍历就可以实现字 ...
- poj1128 拓扑序(DFS)
题意:给出一张图,它是由一系列字母框按一定顺序从下到上摆放,因此上面的字母框会覆盖一部分下面的字母框,确保每个字母框的四条边都至少会出现一个点,要求输出所有可行的摆放顺序,字典序从小到大输出. 首先可 ...
- poj3687 拓扑序
题意:有编号 1-n 的球,每个球的质量不同,质量从 1 到 n 不等,给出一系列比较,分别是两个编号的球的大小关系,求一个序列满足上述关系,并且从编号 1 开始依次选择可选的最小质量,输出每个球的质 ...
随机推荐
- Bootstrap 提示工具(Tooltip)插件方法的用法
方法 下面是一些提示工具(Tooltip)插件中有用的方法: 方法 描述 实例 Options: .tooltip(options) 向元素集合附加提示工具句柄. $().tooltip(option ...
- SQL Server 游标的应用
----------------SQL游标应用----------------- 今天由于业务需求,需要在存储过程中实现有一个表的主键去匹配在另一个表中作为外键所对应的数值 ,若在C#中则非常简单只需 ...
- linux简单常用命令
除了yum命令,还有些简单的命令,在此记录一下,加深记忆: free -h 查询内存和交换分区. rpm -qa | grep libaio 查看当前环境是否安装某rpm软件包
- mutt+msmtp做linux邮件客户端
mutt+msmtp做linux邮件客户端 1. 安装配置msmtp l 安装 wget https://sourceforge.net/projects/msmtp/files/msmtp/1.4 ...
- python生成四位随机数
有些时候需要发送短信给用户生成四位随机数字,这里在python中我们可以根据python自带的标准库random和string来实现. random下有三个可以随机取数的函数,分别是choice,ch ...
- (68)zabbix windows性能计数器使用详解
概述 windows下的性能计数器让zabbix监控更加轻松,直接获取性能计数器的数值即可完成windows监控.性能计数器如下: 1 perf_counter["\Processor( ...
- 【android】签署应用采用相同证书的用处
在应用的预期生命周期内,您应使用相同证书签署所有 APK 应用升级:当系统安装应用的更新时,它会比较新版本和现有版本中的证书.如果证书匹配,则系统允许更新.如果您使用不同的证书签署新版本,则必须为应用 ...
- 最长公共子序列(LCS)问题
最长公共子串(Longest Common Substirng)和最长公共子序列(Longest Common Subsequence,LCS)的区别为:子串是串的一个连续的部分,子序列则是从不改变序 ...
- poj 1862 2*根号(n1*n2)问题 贪心算法
题意: 有n个数,要把其中2个数进行2*根号(n1*n2)操作,求剩下最小的那个数是多少? 哭诉:看题目根本没看出来要让我做这个操作. 思路: 每次把最大的,次大的拿出来进行操作 用"优先队 ...
- TCP缓冲区大小及限制
这个问题在前面有的部分已经涉及,这里在重新总结下.主要参考UNIX网络编程. (1)数据报大小IPv4的数据报最大大小是65535字节,包括IPv4首部.因为首部中说明大小的字段为16位.IPv6的数 ...