HDU 4751 2-sat模板题
Divide Groups
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 161 Accepted Submission(s): 62
Problem Description

Input
The input contains several test cases, terminated by EOF. Each case starts with a positive integer n (2<=n<=100), which means the number of people joining in the event. N lines follow. The i-th line contains some integers which are the id of students that the i-th student knows, terminated by 0. And the id starts from 1.
Output
If divided successfully, please output "YES" in a line, else output "NO".
Sample Input
3
3 0
1 0
1 2 0
Sample Output
YES
由于数据范围很小,直接开二维数组标记两个节点之间的关系,由于题目要求一个组内任意两个人都相互认识,因此对于任意两人,只要不是相互认识,就根据矛盾关系建边,然后2-sat判定。
贴两份代码:
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<string> using namespace std; int head[250],tol,mark[2000],S[2000],c,n,flag[300][300]; struct node { int next,to; }edge[900000]; void add(int u,int v) { edge[tol].to=v; edge[tol].next=head[u]; head[u]=tol++; } bool dfs(int x) { if(mark[x^1])return 0; if(mark[x])return 1; mark[x]=1; S[c++]=x; for(int i=head[x];i!=-1;i=edge[i].next) { int v=edge[i].to; if(!dfs(v))return 0; } return 1; } 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]]=0; if(!dfs(i+1))return 0; } } return 1; } int main() { int i,j,k,T,t; while(~scanf("%d",&n)) { memset(flag,0,sizeof(flag)); memset(head,-1,sizeof(head));tol=0; memset(mark,0,sizeof(mark));c=0; for(i=1;i<=n;i++) { while(~scanf("%d",&j)&&j)flag[i][j]=1; } for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) if(flag[i][j]==0||flag[j][i]==0) { int p,q; p=i-1;q=j-1; add(2*p,2*q+1); add(2*q,2*p+1); add(2*p+1,2*q); add(2*q+1,2*p); } if(solve())puts("YES"); else puts("NO"); } return 0; }
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<string> using namespace std; struct node { int to,next; }edge[900000]; int head[300],tol,low[300],dfn[300],indexx,Stack[300],instack[300],belong[300],scc,top,flag[300][300],n; void add(int u,int v) { edge[tol].to=v; edge[tol].next=head[u]; head[u]=tol++; } void tarjin(int u) { low[u]=dfn[u]=++indexx; Stack[top++]=u;instack[u]=1; int i,v; for(int i=head[u];i!=-1;i=edge[i].next) { v=edge[i].to; if(!dfn[v]) { tarjin(v); if(low[u]>low[v])low[u]=low[v]; } else if(instack[v]&&low[u]>dfn[v])low[u]=dfn[v]; } if(low[u]==dfn[u]) { scc++; do { v=Stack[--top]; instack[v]=0; belong[v]=scc; }while(u!=v); } } int solve() { memset(dfn,0,sizeof(dfn)); memset(instack,0,sizeof(instack)); memset(belong,0,sizeof(belong)); indexx=top=scc=0; for(int i=0;i<2*n;i++)if(!dfn[i])tarjin(i); //cout<<tol<<" "<<scc<<endl; for(int i=0;i<n;i++)if(belong[2*i]==belong[2*i+1])return 0; return 1; } int main() { int i,j,k,T,t; while(~scanf("%d",&n)) { memset(flag,0,sizeof(flag)); memset(head,-1,sizeof(head));tol=0; for(i=1;i<=n;i++) { while(~scanf("%d",&j)&&j)flag[i][j]=1; } for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) if(flag[i][j]==0||flag[j][i]==0) { int p,q; p=i-1;q=j-1; add(2*p,2*q+1); add(2*q,2*p+1); add(2*p+1,2*q); add(2*q+1,2*p); } if(solve())puts("YES"); else puts("NO"); } return 0; }

浙公网安备 33010602011771号