[2-SAT] [JSOI2010] Feast

Methods and feel similar solution to a problem, but the solution to a problem to write a good Fana ... it is not tired, is very complex

It is recommended to open an array that represents the current number of click or do not choose, so after their own management ideas will be more clearly

However, I transferred an hour only to find I was wrong ...... Tarjan

 

This question is for each dish to discuss the two cases, each case there are two options selected and not selected

Therefore, the equivalent of a dish can be split into each of four points 

  1. election practices M-

  2. Uncheck practice M-

  3. The election practices H-

  4. The approach is not selected from H-

 

Obviously the title in the given conditions or, but do not just have a problem in the given conditions, there is an implied condition : dish there is only one practice!

Then follow a routine like 2-sat

Code $ bb [i] [j] [k] $ array is the i represents the current course, practice j: 1/2, is selected or not selected k: 0/1

After adding this side will be very clear and concise

 

 

 1 #include<bits/stdc++.h>
 2 #define writeln(x)  write(x),puts("")
 3 #define writep(x)   write(x),putchar(' ')
 4 using namespace std;
 5 inline int read(){
 6     int ans=0,f=1;char chr=getchar();
 7     while(!isdigit(chr)){if(chr=='-') f=-1;chr=getchar();}
 8     while(isdigit(chr)){ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
 9     return ans*f;
10 }void write(int x){
11     if(x<0) putchar('-'),x=-x;
12     if(x>9) write(x/10);
13     putchar(x%10+'0');
14 }const int M = 2e4+5;
15 int head[M],nxt[M],ver[M],tot,T,n,m,bb[M][3][3],dfn[M],low[M],ins[M],sta[M],top,color,col[M];
16 char s1[M],s2[M];
17 struct Judge{int type[2],x[2];}J[M];
18 inline void add(int x,int y){ver[++tot]=y,nxt[tot]=head[x],head[x]=tot;}
19 void Tarjan(int x){
20     dfn[x]=low[x]=++T;ins[x]=1;sta[top++]=x;
21     for(int i=head[x];i;i=nxt[i]){
22         if(!dfn[ver[i]])Tarjan(ver[i]),low[x]=min(low[x],low[ver[i]]);
23         else if(ins[ver[i]]==1) low[x]=min(low[x],dfn[ver[i]]);
24     }if(low[x]==dfn[x]){++color;
25         do{    col[sta[--top]]=color;
26             ins[sta[top]]=-1;
27         }while(sta[top]!=x);
28     }return;
29 }inline void Init(){
30     memset(low,0,sizeof(low)),memset(dfn,0,sizeof(dfn)),memset(ins,0,sizeof(ins));
31     memset(col,0,sizeof(col)),memset(head,0,sizeof(head));tot=T=color=0;
32     n=read(),m=read();
33     for(int i=1;i<=m;i++){
34         scanf("%s%s",s1,s2);
35         int l1=strlen(s1),l2=strlen(s2);
36         if(s1[0]=='m')J[i].type[0]=1;else J[i].type[0]=2;
37         if(s2[0]=='m')J[i].type[1]=1;else J[i].type[1]=2;
38         int p=1,ans=0;
39         while(isdigit(s1[p])&&p<=l1){ans=(ans<<3)+(ans<<1)+s1[p]-48;++p;}
40         J[i].x[0]=ans;p=1,ans=0;
41         while(isdigit(s2[p])&&p<=l2){ans=(ans<<3)+(ans<<1)+s2[p]-48;++p;}
42         J[i].x[1]=ans;
43     }return;
44 }inline void Make_Graph(){
45     for(int i=1;i<=n;i++)bb[i][1][1]=i,bb[i][1][0]=n+i,bb[i][2][1]=2*n+i,bb[i][2][0]=3*n+i;
46     for(int i=1;i<=m;i++){
47         int x=J[i].type[0],a=J[i].x[0],y=J[i].type[1],b=J[i].x[1];
48         add(bb[a][x][0],bb[b][y][1]),add(bb[b][y][0],bb[a][x][1]);
49         add(bb[i][1][1],bb[i][2][0]),add(bb[i][2][1],bb[i][1][0]);
50     }
51 }inline void Solve(){
52     for(int i=1;i<=n*4;i++)if(!dfn[i])Tarjan(i);
53     for(int i=1;i<=n;i++)if(col[bb[i][1][0]]==col[bb[i][1][1]]||col[bb[i][2][1]]==col[bb[i][2][0]])return puts("BAD"),void();
54     puts("GOOD");
55 }int main(){
56     int T=read();
57     while(T--)Init(),Make_Graph(),Solve();
58     return 0;
59 }

Guess you like

Origin www.cnblogs.com/zhenglw/p/11627289.html