日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P3825-[NOI2017]游戏【2-SAT】

發布時間:2023/12/3 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P3825-[NOI2017]游戏【2-SAT】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/P3825


題目大意

nnn場比賽,對于場地aaa不能用賽車AAAb,cb,cb,c以此類推),對于場地xxx可以用任何賽車。然后給定mmm條條件形如iIjJi\ I\ j\ Ji?I?j?J表示在第iii場比賽使用賽車III的話那么必須在第jjj場比賽使用賽車JJJ。

求一組合法安排方案


解題思路

因為對于場地xxx我們有三種選擇方法,所以這是一個3?SAT3-SAT3?SAT問題,無法計算。而因為xxx場地數量很少,我們可以枚舉每個場地xxx使用哪輛車(是場地aaa還是場地bbb)即可。

然后就是很普通的2?SAT2-SAT2?SAT問題了,時間復雜度O(2dn)O(2^dn)O(2dn)


codecodecode

#include<cstdio> #include<cstring> #include<algorithm> #include<stack> #define p(n,k) (((n)-1)*6+(k)+1) using namespace std; // 0選a 1不選擇a 2選擇b 3不選擇b 4選擇c 5不選擇c const int N=5e4*6; struct node{int to,next; }a[N*8]; struct quee{int a,b,va,vb; }q[N]; int n,d,m,tot,scc,cnt,ls[N]; int dfn[N],low[N],color[N]; bool ins[N];char s[N]; stack<int> S; void addl(int x,int y,int w){if(w)addl(y,x,0);a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return; } void tarjan(int x){dfn[x]=low[x]=++cnt;S.push(x);ins[x]=1;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(!dfn[y])tarjan(y),low[x]=min(low[x],low[y]);else if(ins[y])low[x]=min(low[x],dfn[y]);}if(dfn[x]==low[x]){++scc;while(S.top()!=x){color[S.top()]=scc;ins[S.top()]=0;S.pop();}color[S.top()]=scc;ins[S.top()]=0;S.pop();}return; } bool solve(){memset(ls,0,sizeof(ls));memset(dfn,0,sizeof(dfn));cnt=scc=tot=0;for(int i=1;i<=n;i++){if(s[i]=='a'){addl(p(i,0),p(i,1),0);//不能選a addl(p(i,2),p(i,5),1);//選b不選c addl(p(i,4),p(i,3),1);//選c不選b }if(s[i]=='b'){addl(p(i,2),p(i,3),0);//不能選b addl(p(i,0),p(i,5),1);//選a不選c addl(p(i,4),p(i,1),1);//選c不選a }if(s[i]=='c'){addl(p(i,4),p(i,5),0);//不能選caddl(p(i,0),p(i,3),1);//選a不選baddl(p(i,2),p(i,1),1);//選b不選a }}for(int i=1;i<=m;i++){addl(p(q[i].a,q[i].va),p(q[i].b,q[i].vb),0);addl(p(q[i].b,q[i].vb+1),p(q[i].a,q[i].va+1),0);}for(int i=1;i<=n*6;i++)if(!dfn[i])tarjan(i);for(int i=1;i<=n;i++)if(color[p(i,0)]==color[p(i,1)]||color[p(i,2)]==color[p(i,3)]||color[p(i,4)]==color[p(i,5)]){return 0;}for(int i=1;i<=n;i++){if(color[p(i,0)]<color[p(i,1)])printf("A");else if(color[p(i,2)]<color[p(i,3)])printf("B");else if(color[p(i,4)]<color[p(i,5)])printf("C");}return 1; } int main() {scanf("%d%d",&n,&d);scanf("%s",s+1);d=0;int wz[10];for(int i=1;i<=n;i++)if(s[i]=='x')wz[++d]=i;scanf("%d",&m);for(int i=1;i<=m;i++){int a,b,va,vb;char oa[3],ob[3];scanf("%d %s %d %s",&q[i].a,oa,&q[i].b,ob);if(oa[0]=='A')va=0;else q[i].va=(oa[0]=='B')?2:4;if(ob[0]=='A')vb=0;else q[i].vb=(ob[0]=='B')?2:4;}int MS=1<<d;for(int i=0;i<MS;i++){for(int j=1;j<=d;j++)s[wz[j]]='a'+((i>>j)&1);if(solve())return 0;}printf("-1"); } /* 5 2 acxax 10 2 B 1 A 3 C 4 C 4 B 3 C 5 B 3 B 2 B 3 A 3 A 2 A 5 B 1 C 3 B 1 B 2 C 4 C 4 B 2 A */

總結

以上是生活随笔為你收集整理的P3825-[NOI2017]游戏【2-SAT】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。