題解 洛谷 P3825 NOI2017 遊戲

2022-05-06 20:06:10 字數 1891 閱讀 2521

從題麵中四元組\((i,h_i,j,h_j)\)限制選擇車子型號,不難想到這題要用\(2-sat\)解決。

考慮轉化為\(2-sat\)模型,發現除地圖\(x\)外,其他地圖都只有兩種車子型號可以參加,那麼就把這兩種型號轉化為兩種狀態。

若\(s_i=a\),則狀態為\(b\)和\(c\)。

若\(s_i=b\),則狀態為\(a\)和\(c\)。

若\(s_i=c\),則狀態為\(a\)和\(b\)。

然後討論四元組的情況,設\(i\)為輸入的狀態,\(i^\prime\)為另乙個狀態。

若在第\(i\)場,\(h_i\)不可用,則不進行連邊。

若在第\(i\)場,\(h_i\)可用,在第\(j\)場,\(h_j\)不可用,則從\(i\)向\(i^\prime\)連邊,表示不能選\(i\)。

若兩個都可用,則從\(i\)向\(j\)連邊,表示若選\(i\),則一定選\(j\),同時從\(j^\prime\)向\(i^\prime\)連邊,這裡表示若沒有選\(j\),則一定沒有選\(i\)。

繼續考慮如何處理地圖\(x\),發現其數量\(d\leqslant8\),資料規模很小,那麼我們就可以用\(dfs\)將其所有可能的情況列舉一遍,再檢查是否合法。

我們只需考慮地圖\(x\)等價於地圖\(a\)和地圖\(b\)兩種情況,因為此時已經包括\(a,b,c\)三種車型了。

時間複雜度為\(o(2^d(n+m))\)。

實現細節還是蠻多的,不清楚的就看**吧。

\(code:\)

#include#define maxn 1000010

using namespace std;

templateinline void read(t &x)

while(isdigit(c))

if(flag)x=-x;

}int n,d,m,x_cnt;

bool flag;

char s[maxn],a[5],b[5],c1[maxn],c2[maxn];

int pos[maxn];

struct node

t[maxn];

struct edge

e[maxn];

int head[maxn],edge_cnt;

void add(int from,int to)

; head[from]=edge_cnt;

}int dfn_cnt,co_cnt,top;

int dfn[maxn],low[maxn],co[maxn],st[maxn];

bool vis[maxn];

void tarjan(int x)

else if(vis[y])

low[x]=min(low[x],dfn[y]);

}if(low[x]==dfn[x])

while(now!=x);

}}bool check()

void clear()

void work()

add(x+(a==c2[x])*n,y+(b==c2[y])*n);

add(y+(b==c1[y])*n,x+(a==c1[x])*n);

}if(check())

}}void dfs(int x)

int now=pos[x];

s[now]='a',c1[now]='b',c2[now]='c',dfs(x+1);

s[now]='b',c1[now]='a',c2[now]='c',dfs(x+1);

}int main()

read(m);

for(int i=1;i<=m;++i)

dfs(1);

if(!flag) printf("-1");

return 0;

}

題解 P3825 NOI2017 遊戲

dfs 2 sat被卡得好開心啊 這道題目乍一看是一道 3 sat 的題目,變數是每個地圖,選擇是車的型別。但要注意乙個事實 除了那d個地圖之外,其它的地圖事實上只有2種選擇。而對於那d個x型地圖,我們可以窮舉假設它是a型或b型,因為a型 b型的合法選擇的並還是x型,所以不影響答案。接下來就是連邊的...

洛谷P2048 NOI2010 超級鋼琴 題解

近期發現這篇題解有點爛,更新一下,刪繁就簡,詳細重點。多加了注釋。就醬紫啦!我們需要先算美妙度的字首和,並初始化rmq。迴圈 i 從 1 到 n 因為以i為起點的和弦終點必定是 i l 1 到 i r 1 之間,所以只要在區間內用rmq取超級和弦,並加入以美妙度從小排到大的優先佇列中。取出堆頂元素,...

題解 洛谷P5767 NOI1997 最優乘車

題面 一道很經典的最短路模型轉換問題。考慮如何建圖。我們可以發現,對於每一條公交線路,可以將這條線路上 可以到達的兩個點 連一條權值為 1 的邊。獲取一條公交線路上的每乙個點可以使用讀取每乙個字元的方式,注意要先讀取第一行的換行符。然後就是普通的 bfs 求圖的最短路問題了。最後注意特判輸出no和 ...