题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4665
本题的2-SAT建图颇为复杂,有时间再来填坑(自己写的一直挂着,标程建图太复杂了)。。。然后用暴力搜索,用一个栈保存第一个序列就可以了,因为题目是SPG,并且重复的最多只有四个,所以搜索很好过。。
1 //STATUS:C++_AC_62MS_276KB 2 #include <functional> 3 #include <algorithm> 4 #include <iostream> 5 //#include <ext/rope> 6 #include <fstream> 7 #include <sstream> 8 #include <iomanip> 9 #include <numeric> 10 #include <cstring> 11 #include <cassert> 12 #include <cstdio> 13 #include <string> 14 #include <vector> 15 #include <bitset> 16 #include <queue> 17 #include <stack> 18 #include <cmath> 19 #include <ctime> 20 #include <list> 21 #include <set> 22 #include <map> 23 using namespace std; 24 //#pragma comment(linker,"/STACK:102400000,102400000") 25 //using namespace __gnu_cxx; 26 //define 27 #define pii pair<int,int> 28 #define mem(a,b) memset(a,b,sizeof(a)) 29 #define lson l,mid,rt<<1 30 #define rson mid+1,r,rt<<1|1 31 #define PI acos(-1.0) 32 //typedef 33 typedef __int64 LL; 34 typedef unsigned __int64 ULL; 35 //const 36 const int N=2010; 37 const int INF=0x3f3f3f3f; 38 const int MOD= 1000000007,STA=8000010; 39 const LL LNF=1LL<<55; 40 const double EPS=1e-9; 41 const double OO=1e30; 42 const int dx[4]={-1,0,1,0}; 43 const int dy[4]={0,1,0,-1}; 44 const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; 45 //Daily Use ... 46 inline int sign(double x){return (x>EPS)-(x<-EPS);} 47 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;} 48 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;} 49 template<class T> inline T lcm(T a,T b,T d){return a/d*b;} 50 template<class T> inline T Min(T a,T b){return a<b?a:b;} 51 template<class T> inline T Max(T a,T b){return a>b?a:b;} 52 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);} 53 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);} 54 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));} 55 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));} 56 //End 57 58 int num[N],sta[N],vis[N]; 59 int T,n,top1,top2,mid; 60 61 bool dfs(int u) 62 { 63 if(top2==mid)return true; 64 if(top1<mid){ 65 vis[u]=0; 66 sta[top1++]=num[u]; 67 if(dfs(u+1))return true; 68 top1--; 69 } 70 if(num[u]==sta[top2]){ 71 vis[u]=1; 72 top2++; 73 if(dfs(u+1))return true; 74 vis[u]=0; 75 top2--; 76 } 77 return false; 78 } 79 80 int main(){ 81 // freopen("in.txt","r",stdin); 82 int i,j; 83 scanf("%d",&T); 84 while(T--) 85 { 86 scanf("%d",&n); 87 mid=n>>1; 88 for(i=0;i<n;i++) 89 scanf("%d",&num[i]); 90 91 top1=top2=0; 92 dfs(0); 93 94 for(i=0;i<n;i++) 95 printf("%d",vis[i]); 96 putchar('\n'); 97 } 98 return 0; 99 }
2-SAT(WA):
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 /* WA */ 2 #include <functional> 3 #include <algorithm> 4 #include <iostream> 5 //#include <ext/rope> 6 #include <fstream> 7 #include <sstream> 8 #include <iomanip> 9 #include <numeric> 10 #include <cstring> 11 #include <cassert> 12 #include <cstdio> 13 #include <string> 14 #include <vector> 15 #include <bitset> 16 #include <queue> 17 #include <stack> 18 #include <cmath> 19 #include <ctime> 20 #include <list> 21 #include <set> 22 #include <map> 23 using namespace std; 24 //#pragma comment(linker,"/STACK:102400000,102400000") 25 //using namespace __gnu_cxx; 26 //define 27 #define pii pair<int,int> 28 #define mem(a,b) memset(a,b,sizeof(a)) 29 #define lson l,mid,rt<<1 30 #define rson mid+1,r,rt<<1|1 31 #define PI acos(-1.0) 32 //typedef 33 typedef __int64 LL; 34 typedef unsigned __int64 ULL; 35 //const 36 const int N=2010; 37 const int INF=0x3f3f3f3f; 38 const int MOD= 1000000007,STA=8000010; 39 const LL LNF=1LL<<55; 40 const double EPS=1e-9; 41 const double OO=1e30; 42 const int dx[4]={-1,0,1,0}; 43 const int dy[4]={0,1,0,-1}; 44 const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; 45 //Daily Use ... 46 inline int sign(double x){return (x>EPS)-(x<-EPS);} 47 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;} 48 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;} 49 template<class T> inline T lcm(T a,T b,T d){return a/d*b;} 50 template<class T> inline T Min(T a,T b){return a<b?a:b;} 51 template<class T> inline T Max(T a,T b){return a>b?a:b;} 52 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);} 53 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);} 54 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));} 55 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));} 56 //End 57 58 struct Edge{ 59 int u,v; 60 }e[N<<4]; 61 62 int first[N<<1],next[N<<4],vis[N<<1],S[N<<1]; 63 int num[N]; 64 int T,n,mt,cnt; 65 66 void adde(int a,int b) 67 { 68 e[mt].u=a,e[mt].v=b; 69 next[mt]=first[a];first[a]=mt++; 70 } 71 72 int dfs(int u) 73 { 74 if(vis[u^1])return 0; 75 if(vis[u])return 1; 76 int i; 77 vis[u]=1; 78 S[cnt++]=u; 79 for(i=first[u];i!=-1;i=next[i]){ 80 if(!dfs(e[i].v))return 0; 81 } 82 return 1; 83 } 84 85 int Twosat() 86 { 87 int i,j; 88 for(i=0;i<n;i+=2){ 89 if(vis[i] || vis[i^1])continue; 90 cnt=0; 91 if(!dfs(i)){ 92 while(cnt)vis[S[--cnt]]=0; 93 if(!dfs(i^1))return 0; 94 } 95 } 96 return 1; 97 } 98 99 int cnt2[N],tot[N],w[N][4]; 100 void Init() 101 { 102 int i,j,t; 103 mt=0;mem(vis,0); 104 mem(first,-1); 105 mem(tot,0); 106 for(i=0;i<n;i++)w[num[i]][tot[num[i]]++]=i; 107 mem(cnt2,0); 108 for(i=0;i<n;i++){ 109 t=num[i]; 110 cnt2[t]++; 111 if(cnt2[t]==1){ 112 adde((i<<1)^1,i<<1); 113 adde(i<<1,(w[t][tot[t]-1]<<1)^1); 114 adde(w[t][tot[t]-1]<<1,(i<<1)^1); 115 if(tot[t]==4){ 116 for(j=w[t][1]+1;j<n;j++){ 117 if(w[num[j]][1]==j && w[num[j]][0]<j && w[num[j]][0]>i){ 118 adde(i<<1,(w[t][1]<<1)^1); 119 break; 120 } 121 } 122 } 123 } 124 else if(cnt2[t]==3){ 125 adde(w[t][1]<<1,(w[t][2]<<1)^1); 126 adde((w[t][1]<<1)^1,w[t][2]<<1); 127 adde(w[t][2]<<1,(w[t][1]<<1)^1); 128 adde((w[t][2]<<1)^1,w[t][1]<<1); 129 } 130 } 131 } 132 133 int main(){ 134 freopen("in.txt","r",stdin); 135 int i,j; 136 scanf("%d",&T); 137 while(T--) 138 { 139 scanf("%d",&n); 140 for(i=0;i<n;i++) 141 scanf("%d",&num[i]); 142 143 Init(); 144 n<<=1; 145 int t=Twosat(); 146 // printf("%d\n",t); 147 148 for(i=0;i<n;i+=2) 149 printf("%d",vis[i]); 150 putchar('\n'); 151 } 152 return 0; 153 }