HDU_1824_Let's go home(2-SAT)
2014-09-12 10:00
387 查看
题型:图论
题意:
中文题,不赘述~
原题戳http://acm.hdu.edu.cn/showproblem.php?pid=1824
分析:
2-SAT解决这样的问题,有一些点,存在敌对关系,如选A就不选B;或者是友好关系,如选A必须选B,求解最后是否能够让所有的点分在两个集合互相对立的集合中。
所谓“2”,指的是,每一个点都有两个属性,即A与~A。
所谓SAT,指的是“可适定的”。
假设选A就不选B,那么有布尔表达式A&~B成立。
假设选A必须选B,那么有布尔表达式A&B成立。
假设有N个点,将每个点分成两个,A和~A。建图时,有友好关系的点建边。
例如:若A与B是友好关系,那么A与 B建边A-> B;
若A与B是敌对关系,那么A与~B建边A->~B。
然后跑一遍Tarjan强连通缩点,如果A与~A在一个环内,那么就无法分成两个集合;否则可以成功分成两个集合。
因此,2-SAT的重点就在于建图,图建好了之后,模板一跑就可以解决了~
对于本题,由于队伍T<=1000,且每个队只有一个队长,所以可以设定1000*2个点。对集训成员重新编号,若队长为A,则两名队员映射为~A。然后根据题意建图,套2-SAT模板即可。
代码:
题意:
中文题,不赘述~
原题戳http://acm.hdu.edu.cn/showproblem.php?pid=1824
分析:
2-SAT解决这样的问题,有一些点,存在敌对关系,如选A就不选B;或者是友好关系,如选A必须选B,求解最后是否能够让所有的点分在两个集合互相对立的集合中。
所谓“2”,指的是,每一个点都有两个属性,即A与~A。
所谓SAT,指的是“可适定的”。
假设选A就不选B,那么有布尔表达式A&~B成立。
假设选A必须选B,那么有布尔表达式A&B成立。
假设有N个点,将每个点分成两个,A和~A。建图时,有友好关系的点建边。
例如:若A与B是友好关系,那么A与 B建边A-> B;
若A与B是敌对关系,那么A与~B建边A->~B。
然后跑一遍Tarjan强连通缩点,如果A与~A在一个环内,那么就无法分成两个集合;否则可以成功分成两个集合。
因此,2-SAT的重点就在于建图,图建好了之后,模板一跑就可以解决了~
对于本题,由于队伍T<=1000,且每个队只有一个队长,所以可以设定1000*2个点。对集训成员重新编号,若队长为A,则两名队员映射为~A。然后根据题意建图,套2-SAT模板即可。
代码:
#include<iostream> #include<queue> #include<cmath> #include<cstring> #include<cstdio> #include<stack> #define mt(a,b) memset(a,b,sizeof(a)) using namespace std; const int M = 2005; class Twosat { class Tarjan { struct E { int u,v,next; } e[M*M]; int le,head[M],Index,Bcnt,num[M],belong[M],dfn[M],low[M]; bool instack[M]; stack<int> s; void tarjan(int u) { dfn[u]=low[u]=++Index; instack[u]=true; s.push(u); int v; for(int i=head[u]; ~i; i=e[i].next) { v=e[i].v; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(instack[v]) { low[u]=min(low[u],dfn[v]); } } if(dfn[u]==low[u]) { Bcnt++; do { v=s.top(); s.pop(); instack[v]=false; belong[v]=Bcnt; num[Bcnt]++; } while(u!=v); } } public: void init() { le=Index=Bcnt=0; mt(head,-1); mt(num,0); mt(dfn,0); mt(low,0); mt(instack,0); while(!s.empty()) s.pop(); } void add(int u,int v) { e[le].u=u; e[le].v=v; e[le].next=head[u]; head[u]=le++; } void solve(int n) { for(int i=1; i<=n; i++) { if(!dfn[i]) { tarjan(i); } } } int getbcnt() { return Bcnt; } int getbelong(int id) { return belong[id]; } int getnum(int id) { return num[id]; } } T; class Unitenode { struct E { int u,v,next; } e[M*M]; int n,le,head[M],in[M]; bool mat[M][M]; queue<int> q; public: void init(int x) { n=x; le=0; mt(head,-1); mt(in,0); mt(mat,0); for(int i=1; i<=n; i++) mat[i][i]=true; } void add(int u,int v) { if(!mat[u][v]) { in[v]++; mat[u][v]=true; e[le].u=u; e[le].v=v; e[le].next=head[u]; head[u]=le++; } } void solve(int tp[]) { while(!q.empty()) q.pop(); for(int i=1; i<=n; i++) { if(!in[i]) { q.push(i); } } int ret=1; while(!q.empty()) { int u=q.front(); q.pop(); tp[ret++]=u; for(int i=head[u]; ~i; i=e[i].next) { int v=e[i].v; in[v]--; if(!in[v]) { q.push(v); } } } } } U; void unite() { U.init(T.getbcnt()); for(int i=1; i<=n; i++) { for(int j=head[i]; ~j; j=e[j].next) { U.add(T.getbelong(i),T.getbelong(e[j].v)); } } } struct E { int u,v,next; } e[M*M]; int n,le,head[M],tp[M]; bool flag[M]; public: void init(int x) { n=x; T.init(); le=0; mt(head,-1); } void add(int u,int v) { T.add(u,v); e[le].u=u; e[le].v=v; e[le].next=head[u]; head[u]=le++; } bool solve() { T.solve(n); for(int i=1,z=n/2; i<=z; i++) { if(T.getbelong(i)==T.getbelong(i+z))return false; } return true; } void output(bool ans[]) { unite(); U.solve(tp); mt(flag,0); for(int i=T.getbcnt(); i>0; i--) { for(int j=1,y; j<=n; j++) { if(j>n/2)y=j-n/2; else y=j; if(!flag[y]&&T.getbelong(j)==tp[i]) { flag[y]=true; if(j>n/2) { ans[j-n/2]=true; } else { ans[j]=false; } } } } } } gx; int num[3010]; int main() { int t,m; while(~scanf("%d%d",&t,&m)) { int a,b,c; for(int i=1; i<=t; i++) { scanf("%d%d%d",&a,&b,&c); num[a] = i; num[b] = i+t; num[c] = i+t; } gx.init((t+1)*2); while(m--) { scanf("%d%d",&a,&b); a = num[a]; b = num[b]; gx.add(a,b+(b>t?-t:t)); gx.add(b,a+(a>t?-t:t)); } if(gx.solve()) puts("yes"); else puts("no"); } return 0; }
相关文章推荐
- HDU-1824-Let's go home(2-SAT)
- Hdu 1824 Let's go home (2-sat 可行性判定)
- HDU 1824 —— Let's go home(2-SAT)
- hdu 1824 Let's go home(2-sat入门)
- HDU - 1824 Let's go home(2-SAT)
- hdu 1824 Let's go home (2-sat)
- HDU 1824 Let's go home(2-SAT)
- 【HDU】1824 Let's go home 2-sat
- HDU 1824 Let's go home (2-SAT)
- HDU 1824 Let's go home(2-SAT)
- HDU 1824 Let's go home (2-SAT)
- hdu 1824 Let's go home(s-sat)
- HDU 1824 Let's go home 2-sat判断可行解
- HDU 1824 Let's go home (2-SAT判断)
- HDU 1824 Let's go home(2-sat)
- HDU1824-Let's go home(2-SAT)
- HDU 1824 Let's go home (2-SAT判定)
- hdu 1824 Let's go home【2-SAT------强连通Tarjan】
- HDU 1824 Let's go home (2-SAT判定)
- HDU 1824 Let's go home 2-sat基础