大概学了一下2-SAT,写了一道模板和一道USACO
输出一个方案的话,tarjan缩点后倒着拓扑,染色输出。
求任何解下选哪个就得枚举每个点dfs来判断选哪个。
HIT 1917(2-sat模板)
#include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #include<cmath> #include<map> #define ll long long using namespace std; const int maxn=16010,inf=1e9; struct poi{int too,pre,x;}e[maxn*10],e2[maxn*10]; int last[maxn],last2[maxn],dfn[maxn],low[maxn],col[maxn],lack[maxn],ru[maxn],rs[maxn],st[maxn],op[maxn]; int n,m,x,y,z,tot,tot2,tott,top,color,flag; void read(int &k) { int f=1;k=0;char c=getchar(); while(c<‘0‘||c>‘9‘)c==‘-‘&&(f=-1),c=getchar(); while(c<=‘9‘&&c>=‘0‘)k=k*10+c-‘0‘,c=getchar(); k*=f; } void add(int x,int y){e[++tot].too=y;e[tot].x=x;e[tot].pre=last[x];last[x]=tot;} void add2(int x,int y){e2[++tot2].too=y;e2[tot2].x=x;e2[tot2].pre=last2[x];last2[x]=tot2;} int next(int x){return x&1?x+1:x-1;} void tarjan(int x) { dfn[x]=low[x]=++tott;st[++top]=x;lack[x]=top; for(int i=last[x];i;i=e[i].pre) if(!dfn[e[i].too])tarjan(e[i].too),low[x]=min(low[x],low[e[i].too]); else if(!col[e[i].too])low[x]=min(low[x],dfn[e[i].too]); if(dfn[x]==low[x])for(color++;top>=lack[x];top--)col[st[top]]=color; } void topsort() { top=0;for(int i=1;i<=color;i++)if(!ru[i])st[++top]=i; while(top) { int now=st[top--]; if(!rs[now])rs[now]=1,rs[op[now]]=2; for(int i=last2[now];i;i=e2[i].pre) if(!(--ru[e2[i].too]))st[++top]=e2[i].too; } } void clr() { color=top=tot=tot2=flag=0; memset(col,0,sizeof(col)); memset(dfn,0,sizeof(dfn)); memset(ru,0,sizeof(ru)); memset(rs,0,sizeof(rs)); memset(lack,0,sizeof(lack)); memset(last,0,sizeof(last)); memset(last2,0,sizeof(last2)); } int main() { while(~scanf("%d%d",&n,&m)) { clr(); for(int i=1;i<=m;i++)read(x),read(y),add(x,next(y)),add(y,next(x)); for(int i=1;i<=2*n;i++)if(!dfn[i])tarjan(i); for(int i=1;i<=n;i++)if(col[i<<1]==col[next(i<<1)]){printf("NIE\n");flag=1;break;} else op[col[i<<1]]=col[next(i<<1)],op[col[next(i<<1)]]=col[i<<1]; if(flag)continue; for(int i=1;i<=tot;i++)if(col[e[i].x]!=col[e[i].too])add2(col[e[i].too],col[e[i].x]),ru[col[e[i].x]]++; topsort(); for(int i=1;i<=n;i++)if(rs[col[(i<<1)]]==1)printf("%d\n",i<<1);else printf("%d\n",next(i<<1)); } return 0; }
bzoj 2199
#include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> using namespace std; const int maxn=500010; struct poi{int x,too,pre;}e[maxn],e2[maxn]; int n,m,t,tot,tot2,tott,top,color; int dfn[maxn],low[maxn],col[maxn],last[maxn],last2[maxn],v[maxn],st[maxn],lack[maxn]; char ans[maxn]; void read(int &k) { int f=1;k=0;char c=getchar(); while(c<‘0‘||c>‘9‘)c==‘-‘&&(f=-1),c=getchar(); while(c<=‘9‘&&c>=‘0‘)k=k*10+c-‘0‘,c=getchar(); k*=f; } int readd() { int x;read(x);char c=getchar(); while(c!=‘Y‘&&c!=‘N‘)c=getchar(); if(c==‘Y‘)return (x<<1)^1; return x<<1; } void add(int x,int y){e[++tot].too=y;e[tot].x=x;e[tot].pre=last[x];last[x]=tot;} void add2(int x,int y){e2[++tot2].too=y;e2[tot2].x=x;e2[tot2].pre=last2[x];last2[x]=tot2;} void dfs(int x) { v[x]=t; for(int i=last2[x];i;i=e2[i].pre) if(v[e2[i].too]!=t)dfs(e2[i].too); } bool check(int x) { t++;dfs(x); for(int i=1;i<=n;i++) if(v[col[(i<<1)^1]]==t&&v[col[i<<1]]==t)return 0; return 1; } void tarjan(int x) { dfn[x]=low[x]=++tott;st[++top]=x;lack[x]=top; for(int i=last[x];i;i=e[i].pre) if(!dfn[e[i].too])tarjan(e[i].too),low[x]=min(low[x],low[e[i].too]); else if(!col[e[i].too])low[x]=min(low[x],dfn[e[i].too]); if(dfn[x]==low[x])for(color++;top>=lack[x];top--)col[st[top]]=color; } void dfss(int x) { v[x]=1; for(int i=last[x];i;i=e[i].pre) if(!v[e[i].too])dfss(e[i].too); } int main() { read(n);read(m); for(int i=1;i<=m;i++) { int x=readd(),y=readd(); add(x^1,y);add(y^1,x); } for(int i=2;i<=((n<<1)^1);i++)if(!dfn[i])tarjan(i); for(int i=1;i<=n;i++)if(col[(i<<1)^1]==col[i<<1]){puts("IMPOSSIBLE");return 0;} for(int i=1;i<=tot;i++)if(col[e[i].x]!=col[e[i].too])add2(col[e[i].x],col[e[i].too]); for(int i=1;i<=n;i++) { int x=check(col[(i<<1)^1]),y=check(col[i<<1]); if(!(x||y)){puts("IMPOSSIBLE");return 0;} else if(x&&y)ans[i]=‘?‘; else if(x)ans[i]=‘Y‘; else if(y)ans[i]=‘N‘; } for(int i=1;i<=n;i++)putchar(ans[i]); }
时间: 2024-08-02 18:16:53