hdu 1824-Let's go home 2-SAT (模板)
題目鏈接:
http://acm.hdu.edu.cn/showproblem.php?pid=1824
| ? |
Let's go homeTime Limit: 10000/1000 MS (Java/Others)????Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2588????Accepted Submission(s): 1125 ? Problem Description 小時候,鄉(xiāng)愁是一枚小小的郵票,我在這頭,母親在那頭。 ? ?Input 第一行有兩個整數(shù),T和M,1<=T<=1000表示隊伍數(shù),1<=M<=5000表示對數(shù)。 ? ?Output 可行輸出yes,否則輸出no,以EOF為結(jié)束。 ? ?Sample Input ?1 2 0 1 2 0 1 1 2 2 4 0 1 2 3 4 5 0 3 0 4 1 3 1 4 ? ?Sample Output ?yes no ? ?Author 威士忌 ? ?Source HDOJ 2007 Summer Exercise(3)- Hold by Wiskey ? ?Recommend 威士忌???|???We have carefully selected several similar problems for you:??1823?1826?1827?1822?1825? ? ?Statistic?|?Submit?|?Discuss?|?Note |
?
題意:?
????????集訓(xùn)是辛苦的,道路是坎坷的,休息還是必須的。經(jīng)過一段時間的訓(xùn)練,lcy決定讓大家回家放松一下,但是訓(xùn)練還是得照常進(jìn)行,lcy想出了如下回家規(guī)定,每一個隊(三人一隊)或者隊長留下或者其余兩名隊員同時留下;每一對隊員,如果隊員A留下,則隊員B必須回家休息下,或者B留下,A回家。由于今年集訓(xùn)隊人數(shù)突破往年同期最高記錄,管理難度相當(dāng)大,lcy也不知道自己的決定是否可行,所以這個難題就交給你了,呵呵,好處嘛~,免費**漂流一日。
分析:
????????其實就是簡單的2-SAT問題判斷,每個人有兩種選擇:留=0或走=1.
-
然后該2-SAT要滿足兩類條件,第一類是 隊長留 or 另外兩個隊員留.
-
第二類是由M指出的 一對隊員a和b的沖突條件.
????????假設(shè)a b c 組成一個隊,且a是隊長,那么由于隊長a與隊員(b,c)組合二者只能選其一,
TS.add_and_clause(b,0,c,0);//b留c留 TS.add_and_clause(c,0,b,0);//c留b留TS.add_and_clause(a,1,b,0);//a走b留TS.add_and_clause(a,1,c,0);//a走c留TS.add_and_clause(b,1,a,0);//b走a留TS.add_and_clause(c,1,a,0);//c走a留? ? ? 對于另外M個條件的a與b來說有:
?
TS.add_and_clause(a,0,b,1);//a留,導(dǎo)致b走 TS.add_and_clause(b,0,a,1);//b留,導(dǎo)致a走?//注意用的是AND
這樣錯了好幾次
This is the code:
#include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<iomanip> #include<list> #include<map> #include<queue> #include<sstream> #include<stack> #include<string> #include<set> #include<vector> using namespace std; #define PI acos(-1.0) #define pppp cout<<endl; #define EPS 1e-8 #define LL long long #define ULL unsigned long long //1844674407370955161 #define INT_INF 0x3f3f3f3f //1061109567 #define LL_INF 0x3f3f3f3f3f3f3f3f //4557430888798830399 // ios::sync_with_stdio(false); // 那么cin, 就不能跟C的 scanf,sscanf, getchar, fgets之類的一起使用了。 const int dr[]= {0, 0, -1, 1, -1, -1, 1, 1}; const int dc[]= {-1, 1, 0, 0, -1, 1, -1, 1}; int read()//輸入外掛 {int ret=0, flag=0;char ch;if((ch=getchar())=='-')flag=1;else if(ch>='0'&&ch<='9')ret = ch - '0';while((ch=getchar())>='0'&&ch<='9')ret=ret*10+(ch-'0');return flag ? -ret : ret; }const int maxn= 100000+10; struct TwoSAT {int n;//原始圖的節(jié)點數(shù)(未翻倍)vector<int> G[maxn*2];//G[i]==j表示如果mark[i]=true,那么mark[j]也要=truebool mark[maxn*2];//標(biāo)記int S[maxn*2],c;//S和c用來記錄一次dfs遍歷的所有節(jié)點編號void init(int n){this->n=n;for(int i=0; i<2*n; i++)G[i].clear();memset(mark,0,sizeof(mark));}//加入(x,xval)或(y,yval)條件//xval=0表示假,yval=1表示真void add_or_clause(int x,int xval,int y,int yval)//表示或的意思{x=x*2+xval;y=y*2+yval;G[x^1].push_back(y);G[y^1].push_back(x);}//加入(x,xval)且(y,yval)條件//xval=0表示假,yval=1表示真void add_and_clause(int x,int xval,int y,int yval)//表示或的意思{x=x*2+xval;y=y*2+yval;G[x].push_back(y);}//從x執(zhí)行dfs遍歷,途徑的所有點都標(biāo)記//如果不能標(biāo)記,那么返回falsebool dfs(int x){if(mark[x^1])return false;//這兩句的位置不能調(diào)換if(mark[x])return true;mark[x]=true;S[c++]=x;for(int i=0; i<G[x].size(); i++)if(!dfs(G[x][i]))return false;return true;}//判斷當(dāng)前2-SAT問題是否有解bool solve(){for(int i=0; i<2*n; i+=2)if(!mark[i] && !mark[i+1]){c=0;if(!dfs(i)){while(c>0)mark[S[--c]]=false;if(!dfs(i+1))return false;}}return true;} } TS;int main() {//freopen("D:\\chnegxubianji\\inORout\\in.txt", "r", stdin);//freopen("D:\\chnegxubianji\\inORout\\out.txt", "w", stdout);int n,m;while(~scanf("%d%d",&n,&m)){TS.init(n*3);while(n--){int a,b,c;scanf("%d%d%d",&a,&b,&c);TS.add_and_clause(b,0,c,0);//b留c留TS.add_and_clause(c,0,b,0);//c留b留TS.add_and_clause(a,1,b,0);//a走b留//TS.add_and_clause(b,0,a,1);//b留a走TS.add_and_clause(a,1,c,0);//a走c留//TS.add_and_clause(c,0,a,1);//c留a走TS.add_and_clause(b,1,a,0);//b走a留//TS.add_and_clause(a,0,b,1);//a留b走TS.add_and_clause(c,1,a,0);//c走a留//TS.add_and_clause(a,0,c,1);//a留c走//TS.add_and_clause(b,1,c,1);//b走c走//TS.add_and_clause(c,1,b,1);//c走b走}while(m--){int a,b;scanf("%d%d",&a,&b);TS.add_and_clause(a,0,b,1);//a留,導(dǎo)致b走TS.add_and_clause(b,0,a,1);//b留,導(dǎo)致a走}bool flag=TS.solve();if(flag)puts("yes");elseputs("no");}return 0; }?
?
?
總結(jié)
以上是生活随笔為你收集整理的hdu 1824-Let's go home 2-SAT (模板)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iOS7下获取内付费的receipt及r
- 下一篇: web网站服务器宕机应急,web服务器的