Processing math: 11%

LOJ#2305. 「NOI2017」游戏 枚举+2-SAT

调都没调就 1 A 了,开心.   

一些细节:  

1. 当 3 个点中强制一个点不选时,又有 (hi,hj) 这种限制时直接跳过即可.
2. 当有 (h_{i},h_{j})i 这个位置存在,但是 j 不存在的时候显然是不可以选择 i 的,那就直接让 ii' 就行.
3. 2-SAT 的建图始终是有对称性的,即 a->b 就要有 b'->a',这个一定注意.    

code: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <bits/stdc++.h>    
#define N 100009  
#define ll long long
#define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout) 
using namespace std;     
char str[N];  
stack<int>sta; 
int n,D,S,m,edges,scc,tim,tot;  
int vis[N],mark[N],bu[N],ID[2][N],ge[N][4];   
int hd[N],to[N<<1],nex[N<<1],dfn[N],low[N],idx[N]; 
struct data
{
    int i,hi,j,hj;  
}h[N];         
void add(int u,int v)
{
    nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;  
}  
void tarjan(int x)
{
    sta.push(x),low[x]=dfn[x]=++tim;   
    for(int i=hd[x];i;i=nex[i])
    {
        int y=to[i]; 
        if(!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]); 
        else if(!idx[y]) low[x]=min(low[x],dfn[y]); 
    }  
    if(low[x]==dfn[x])
    {
        ++scc; 
        for(;;)
        {
            int u=sta.top(); sta.pop();  
            idx[u]=scc;  
            if(u==x) break
        }
    }
}     
void clr()
{
    for(int i=1;i<=tot;++i) hd[i]=dfn[i]=low[i]=idx[i]=0;  
    for(int i=0;i<=edges;++i)  nex[i]=to[i]=0;  
}
int calc()
{      
    int x,y,z;              
    for(int i=1;i<=n;++i) 
    {
        if(vis[i])
        {
            if(mark[i]==0) str[i]='a';       
            if(mark[i]==1) str[i]='b'
        }
        if(str[i]=='a') ge[i][1]=0,ge[i][2]=1;         
        if(str[i]=='b') ge[i][0]=0,ge[i][2]=1;  
        if(str[i]=='c') ge[i][0]=0,ge[i][1]=1;  
    }
    for(int i=1;i<=m;++i)
    {
        data e=h[i];       
        // 反正肯定不会选        
        if(str[e.i]=='a'+e.hi) continue;         
        // 当前肯定不能选
        if(str[e.j]=='a'+e.hj)
        {  
            add(ID[ge[e.i][e.hi]][e.i],ID[ge[e.i][e.hi]^1][e.i]);   
            continue;  
        }   
        // i->j, j'->i'   
        add(ID[ge[e.i][e.hi]][e.i],ID[ge[e.j][e.hj]][e.j]);  
        add(ID[ge[e.j][e.hj]^1][e.j],ID[ge[e.i][e.hi]^1][e.i]);
    }        
    for(int i=1;i<=tot;++i)  if(!dfn[i])   tarjan(i);     
    int flag=1;  
    for(int i=1;i<=n;++i) if(idx[ID[0][i]]==idx[ID[1][i]]) flag=0;            
    if(flag)
    {
        for(int i=1;i<=n;++i)
        {
            x=ID[0][i],y=ID[1][i];         
            if(str[i]=='a') printf("%c",idx[x]<idx[y]?'B':'C'); 
            if(str[i]=='b') printf("%c",idx[x]<idx[y]?'A':'C');  
            if(str[i]=='c') printf("%c",idx[x]<idx[y]?'A':'B');  
        }
    }  
    clr();  
    return flag;   
}   
int main()
{
    // setIO("input");        
    int x,y,z;
    char a[2],b[2]; 
    scanf("%d%d%s%d",&n,&x,str+1,&m);                
    for(int i=1;i<=m;++i)  
    {  
        scanf("%d%s%d%s",&h[i].i,a,&h[i].j,b); 
        h[i].hi=a[0]-'A',h[i].hj=b[0]-'A';   
    }
    for(int i=1;i<=n;++i)  if(str[i]=='x') vis[i]=1,bu[++D]=i;   
    for(int i=1;i<=n;++i)  ID[0][i]=++tot; 
    for(int i=1;i<=n;++i)  ID[1][i]=++tot;           
    // 0 表示 不选 A
    // 1 表示 不选 B       
    for(int i=0;i<(1<<D);++i)     
    {
        for(int j=0;j<D;++j) 
        {
            if(i&(1<<j)) mark[bu[j+1]]=1;
            else mark[bu[j+1]]=0;         
        }
        if(calc())  return 0; 
    }         
    if(!D&&calc())  return 0;   
    printf("-1");
    return 0;
}

  

posted @   EM-LGH  阅读(140)  评论(0编辑  收藏  举报
编辑推荐:
· .NET 依赖注入中的 Captive Dependency
· .NET Core 对象分配(Alloc)底层原理浅谈
· 聊一聊 C#异步 任务延续的三种底层玩法
· 敏捷开发:如何高效开每日站会
· 为什么 .NET8线程池 容易引发线程饥饿
阅读排行:
· 终于决定:把自己家的能源管理系统开源了!
· [.NET] 使用客户端缓存提高API性能
· 外部H5唤起常用小程序链接规则整理
· C#实现 Winform 程序在系统托盘显示图标 & 开机自启动
· WPF 怎么利用behavior优雅的给一个Datagrid添加一个全选的功能
历史上的今天:
2019-06-09 BZOJ 4278: [ONTAK2015]Tasowanie 后缀数组 + 贪心 + 细节
2019-06-09 BZOJ 1692: [Usaco2007 Dec]队列变换 后缀数组 + 贪心
2019-06-09 luogu P2852 [USACO06DEC]牛奶模式Milk Patterns 后缀数组 + Height数组 + 二分答案 + 扫描
2019-06-09 BZOJ2251 [2010Beijing Wc]外星联络 后缀数组 + Height数组
2019-06-09 [NOI2015]软件包管理器 树链剖分 + 线段树
点击右上角即可分享
微信分享提示