從題麵中四元組\((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和 ...