洛谷P3825 [NOI2017]游戏(2-SAT)

本文探讨了一个复杂的图论问题,通过2-SAT算法处理赛车在不同地图上选择车辆的问题。针对每个地图只能使用两种赛车的限制,文章详细介绍了如何构建图并运用2-SAT算法求解,同时考虑了特殊情况下的枚举策略,最终实现了在多项式时间内找到解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门

 

果然图论的题永远建图最麻烦……看着题解代码的建图过程真的很珂怕……

先不考虑地图$x$,那么每一个地图都只能用两种赛车,于是我们可以用2-SAT来搞,用$i$表示这个地图能用的第一辆车,$i'$表示它能用的第二辆车

至于怎么连边呢,考虑限制条件$(i,h_i,j,h_j)$,如果$i$不能用$h_i$我们直接忽视这个限制条件,如果$j$不能用$h_j$说明无解,于是我们连边$(i,i')$表示如果选了$i$的第一辆车就无解

否则的话就按一般的2-SAT把上面的限制条件连边即可

然后考虑怎么处理地图$x$,因为$d$最大只有$8$,且可行的方案里每一个地图$x$只要用一辆车,于是我们考虑枚举每一个地图$x$哪一辆车不能用,只需要枚举$A$和$B$即可,如果有解,能用$BC$和能用$AC$的方案里一定有一个可行

于是时间复杂度就是$O((n+m)2^d)$

  1 //minamoto
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<cstring>
  5 #define mem(a) (memset(a,0,sizeof(a)))
  6 #define swap(x,y) (x^=y^=x^=y)
  7 #define neg(x) (x>n?x-n:x+n)
  8 using namespace std;
  9 template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
 10 inline int read(){
 11     #define num ch-'0'
 12     char ch;bool flag=0;int res;
 13     while(!isdigit(ch=getchar()))
 14     (ch=='-')&&(flag=true);
 15     for(res=num;isdigit(ch=getchar());res=res*10+num);
 16     (flag)&&(res=-res);
 17     #undef num
 18     return res;
 19 }
 20 inline char getc(){
 21     char ch;while((ch=getchar())!='A'&&ch!='B'&&ch!='C');return ch;
 22 }
 23 const int N=2e5+5;
 24 int head[N],Next[N],ver[N],tot;
 25 inline void add(int u,int v){
 26     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
 27 }
 28 int dfn[N],low[N],bl[N],st[N],num,cnt,top,n,m,d;
 29 void tarjan(int u){
 30     dfn[u]=low[u]=++num,st[++top]=u;
 31     for(int i=head[u];i;i=Next[i]){
 32         int v=ver[i];
 33         if(!dfn[v]) tarjan(v),cmin(low[u],low[v]);
 34         else if(!bl[v]) cmin(low[u],dfn[v]);
 35     }
 36     if(dfn[u]==low[u]) for(++cnt;st[top+1]!=u;--top) bl[st[top]]=cnt;
 37 }
 38 inline void clear(){
 39     mem(head),mem(dfn),mem(bl),mem(st);
 40     tot=num=cnt=0;
 41 }
 42 int a1[N],b1[N],Sooke[N];char s[N],a2[N],b2[N],QAQ[N];
 43 int flag=0;
 44 int tran(int x,char ch){
 45     if(s[x]=='a') return ch=='B'?x:x+n;
 46     if(s[x]=='b'||s[x]=='c') return ch=='A'?x:x+n;
 47     if(ch=='C') return x+n;return x;
 48 }
 49 bool solve(){
 50     clear();
 51     for(int i=1;i<=m;++i)
 52     if(s[a1[i]]!='x'&&s[b1[i]]!='x'){
 53         if(a2[i]==s[a1[i]]-32) continue;
 54         int u=tran(a1[i],a2[i]),v;
 55         if(b2[i]==s[b1[i]]-32){add(u,neg(u));continue;}
 56         v=tran(b1[i],b2[i]),add(u,v),add(neg(v),neg(u));
 57     }else{
 58         char o=s[a1[i]],p=s[b1[i]];
 59         int u,v,x=Sooke[a1[i]],y=Sooke[b1[i]];
 60         if(o=='x'&&p=='x'){
 61             if(a2[i]==QAQ[x]) continue;
 62             u=tran(a1[i],a2[i]);
 63             if(b2[i]==QAQ[y]){add(u,neg(u));continue;}
 64             v=tran(b1[i],b2[i]),add(u,v),add(neg(v),neg(u));
 65         }else if(o=='x'&&p!='x'){
 66             if(a2[i]==QAQ[x]) continue;
 67             u=tran(a1[i],a2[i]);
 68             if(b2[i]==s[b1[i]]-32){add(u,neg(u));continue;}
 69             v=tran(b1[i],b2[i]),add(u,v),add(neg(v),neg(u));
 70         }else{
 71             if(a2[i]==s[a1[i]]-32) continue;
 72             u=tran(a1[i],a2[i]);
 73             if(b2[i]==QAQ[y]){add(u,neg(u));continue;}
 74             v=tran(b1[i],b2[i]),add(u,v),add(neg(v),neg(u));
 75         }
 76     }
 77     for(int i=1,l=n<<1;i<=l;++i) if(!dfn[i]) tarjan(i);
 78     for(int i=1;i<=n;++i) if(bl[i]==bl[i+n]) return 0;
 79     for(int i=1;i<=n;++i)
 80     if(bl[i]<bl[i+n]){
 81         if(s[i]=='a') putchar('B');
 82         else if(s[i]=='b'||s[i]=='c') putchar('A');
 83         else if(QAQ[Sooke[i]]=='A') putchar('B');
 84         else putchar('A');
 85     }else{
 86         if(s[i]=='a'||s[i]=='b') putchar('C');
 87         else if(s[i]=='c') putchar('B');
 88         else if(QAQ[Sooke[i]]=='A') putchar('C');
 89         else putchar('B');
 90     }
 91     return 1;
 92 }
 93 void dfs(int dep){
 94     if(dep>d){
 95         if(!flag) flag=solve();
 96         if(flag) exit(0);
 97         return;
 98     }
 99     QAQ[dep]='A',dfs(dep+1);
100     QAQ[dep]='B',dfs(dep+1);
101 }
102 int main(){
103 //    freopen("testdata.in","r",stdin);
104     n=read(),read();
105     scanf("%s",s+1),m=read();
106     for(int i=1;i<=n;++i) if(s[i]=='x') Sooke[i]=++d;
107     for(int i=1;i<=m;++i)
108     a1[i]=read(),a2[i]=getc(),b1[i]=read(),b2[i]=getc();
109     dfs(1);
110     if(!flag) printf("%d",-1);
111     return 0;
112 }

 

转载于:https://www.cnblogs.com/bztMinamoto/p/9786225.html

jQuery是一种广泛应用于网页开发的JavaScript库。然而,由于其普遍性,jQuery也存在一些安全漏洞,其中之一是跨站脚本攻击(XSS)。 跨站脚本攻击是指攻击者利用网页中的漏洞来注入恶意脚本代码,从而窃取用户敏感信息或者对用户进行各种不良操作。而jQuery的跨站脚本漏洞主要是由于其在处理用户输入时,没有充分验证用户输入的安全性。 这种漏洞的利用方式大致分为两种:一种是对用户输入的数据进行恶意修改,然后以用户的身份执行一些不被授权的操作;另一种是实施钓鱼攻击,诱骗用户点击看似正常的链接,实际上触发了一段恶意代码。 为了防止jQuery的跨站脚本漏洞,我们可以采取以下几个措施: 1. 对用户输入的数据进行严格的验证和过滤,确保输入的内容符合预期的格式和类型,并且不包含恶意代码。 2. 在使用jQuery提供的DOM操作方法时,尽量避免使用innerHTML、outerHTML等操作,可以使用text()、html()等方法来代替,以避免恶意修改DOM结构。 3. 在使用jQuery的AJAX功能时,要注意对返回的数据进行严格的验证和过滤,确保不包含恶意代码。 4. 及时更新jQuery库,以获取最新的安全补丁和修复漏洞。 5. 强制开启CSP(内容安全策略),限制网页中外部资源的加载,避免引入可疑的脚本文件。 总之,要防止jQuery的跨站脚本漏洞,我们需要在代码编写和用户输入处理上加入更多的安全措施,确保用户的信息安全和网页的正常运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值