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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

2-sat模板- 输出可行解

發布時間:2023/12/3 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2-sat模板- 输出可行解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

自己寫的代碼

using namespace std; const int maxn = 1e6; int head[maxn]; int DFN[maxn],LOW[maxn],stk[maxn],visit[maxn],belong[maxn]; vector<int> scc[maxn]; int tot,idx,cnt,sccnum; int n,color[maxn],degree[maxn],pos[maxn]; struct Es{ int v; int next; int cost; }Es[maxn<<1]; vector<int> bkG[maxn]; void init(){ sccnum = tot = idx = cnt = 0; memset(head,-1,sizeof(head)); memset(DFN,0,sizeof(DFN)); memset(LOW,0,sizeof(LOW)); memset(visit,0,sizeof(visit)); memset(color,0,sizeof(color)); memset(degree,0,sizeof(degree));memset(pos,0,sizeof(pos));for(int i = 0;i < maxn;i++) scc[i].clear();for(int i = 0;i < maxn;++i) bkG[i].clear(); } inline void add_edge(int i,int j,int cost = 1){ Es[cnt].v = j; Es[cnt].cost = cost; Es[cnt].next = head[i]; head[i] = cnt++; } void tarjan(int x) {DFN[x]=LOW[x]=++tot;stk[++idx]=x;visit[x]=1;for(int i=head[x];i!=-1;i=Es[i].next){if(!DFN[Es[i].v]) {tarjan(Es[i].v);LOW[x] = min(LOW[x],LOW[Es[i].v]);}else if(visit[Es[i].v ]){ LOW[x] = min(LOW[x],DFN[Es[i].v]);}}if(LOW[x]==DFN[x]){++sccnum;do{int item = stk[idx];belong[item] = sccnum;scc[sccnum].push_back(item);visit[item]=0;idx--;}while(x!=stk[idx+1]);}return ; } bool check(){for(int i = 1;i <= n;i++){if(belong[i] == belong[i+n]) return false;}return true; } bool solve(){for(int i = 1;i <= 2*n;++i )if(!DFN[i]) tarjan(i);if(!check()) return false;for(int i = 1;i <= n;++i){if(!pos[belong[i]]){pos[belong[i]] = belong[i+n];pos[belong[i+n]] = belong[i];}}for(int i = 1;i <= 2*n;++i){for(int e = head[i];e != -1;e = Es[e].next){int v = Es[e].v;if(belong[i] != belong[v]){degree[belong[i]]++;bkG[belong[v]].push_back(belong[i]);}}}queue<int> que;for(int i = 1;i <= sccnum;++i){if(!degree[i])que.push(i);}while(!que.empty()){int u = que.front();que.pop();if(!color[u]){color[u] = 1;color[pos[u]] = 2;}for(int i = 0;i < bkG[u].size();++i){int v = bkG[u][i];degree[v]--;if(!degree[v])que.push(v);}}//在這里準備輸出答案//為1表示選中,為2表示為選中/*for(int i = 1;i <= n;++i){if(color[belong[i]] == 1) {//Yes}else{//No}} */return true; }
//使用方法

1.init()

2.用add_edge建圖

3.用solve()函數求解



總結

以上是生活随笔為你收集整理的2-sat模板- 输出可行解的全部內容,希望文章能夠幫你解決所遇到的問題。

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