BZOJ2255 : [Swerc2010]Palindromic DNA
阿新 • • 發佈:2017-07-16
mic bool 同時 row for break int cpp clu
考慮2-SAT建圖,設$a[i][0..1]$表示$i$變不變,$b[i][0..1]$表示$i$是下降還是上升。
首先相鄰的不能同時動,說明$a[i]$和$a[i+1]$裏最多選一個。
對於$x$和$y$要相等,假設$s[x]\geq s[y]$。
$1.$若$s[x]-s[y]=3$,則視為$1$,並交換$x,y$。
$2.$若$s[x]=s[y]$,那麽它們的任何行動都是相等的:
$a[x][0]\leftrightarrow a[y][0]$
$a[x][1]\leftrightarrow a[y][1]$
$b[x][0]\leftrightarrow b[y][0]$
$b[x][1]\leftrightarrow b[y][1]$
$3.$若$s[x]-s[y]=1$,那麽它們有且僅能動一個,方向也是定的:
$a[x][0]\leftrightarrow a[y][1]$
$a[x][1]\leftrightarrow a[y][0]$
$a[x][1]$和$b[x][0]$最多只能選一個
$a[y][1]$和$b[y][1]$最多只能選一個
$4.$若$s[x]-s[y]=2$,那麽它們都要動,而且方向相反:
$a[x][0]\rightarrow a[x][1]$
$a[y][0]\rightarrow a[y][1]$
$b[x][0]\leftrightarrow b[y][1]$
$b[x][1]\leftrightarrow b[x][0]$
求出SCC,若某個$a[i][0]$和$a[i][1]$在同一個SCC則無解,不需要考慮$b$,因為可以既不上升也不下降。
時間復雜度$O(n+m)$。
#include<cstdio> #include<algorithm> using namespace std; const int N=100010,M=N*4,E=2000000; int n,m,i,j,k,cnt,a[N][2],b[N][2],p[N],g[2][M],v[2][E],nxt[2][E],ed,q[M],t,f[M]; bool vis[M];char s[N]; inline void read(int&a){char c;while(!(((c=getchar())>=‘0‘)&&(c<=‘9‘)));a=c-‘0‘;while(((c=getchar())>=‘0‘)&&(c<=‘9‘))(a*=10)+=c-‘0‘;} inline int getid(char x){ if(x==‘A‘)return 0; if(x==‘G‘)return 1; if(x==‘T‘)return 2; return 3; } inline void add(int x,int y){ v[0][++ed]=y;nxt[0][ed]=g[0][x];g[0][x]=ed; v[1][ed]=x;nxt[1][ed]=g[1][y];g[1][y]=ed; } inline void add2(int x,int y){add(x,y),add(y,x);} inline void check(int x,int y){ if(s[x]<s[y])swap(x,y); int w=s[x]-s[y]; if(w==3)w=1,swap(x,y); if(!w){ add2(a[x][0],a[y][0]); add2(a[x][1],a[y][1]); add2(b[x][0],b[y][0]); add2(b[x][1],b[y][1]); return; } if(w==1){ add2(a[x][0],a[y][1]); add2(a[x][1],a[y][0]); add(a[x][1],b[x][0]); add(b[x][1],a[x][0]); add(a[y][1],b[y][1]); add(b[y][0],a[x][0]); return; } add(a[x][0],a[x][1]); add(a[y][0],a[y][1]); add2(b[x][0],b[y][1]); add2(b[x][1],b[y][0]); } void dfs1(int x){ vis[x]=1; for(int i=g[0][x];i;i=nxt[0][i])if(!vis[v[0][i]])dfs1(v[0][i]); q[++t]=x; } void dfs2(int x,int y){ vis[x]=0;f[x]=y; for(int i=g[1][x];i;i=nxt[1][i])if(vis[v[1][i]])dfs2(v[1][i],y); } int main(){ while(~scanf("%d%d",&n,&m)){ if(!n)return 0; scanf("%s",s); for(i=0;i<n;i++)s[i]=getid(s[i]); for(cnt=i=0;i<n;i++)for(j=0;j<2;j++)a[i][j]=++cnt,b[i][j]=++cnt; for(ed=0,i=1;i<=cnt;i++)g[0][i]=g[1][i]=0; for(i=0;i<n;i++){ if(i)add(a[i][1],a[i-1][0]); if(i+1<n)add(a[i][1],a[i+1][0]); } while(m--){ read(k); for(i=0;i<k;i++)read(p[i]); for(i=0,j=k-1;i<j;i++,j--)check(p[i],p[j]); } for(t=0,i=1;i<=cnt;i++)if(!vis[i])dfs1(i); for(i=cnt;i;i--)if(vis[q[i]])dfs2(q[i],q[i]); for(i=0;i<n;i++)if(f[a[i][0]]==f[a[i][1]])break; puts(i<n?"NO":"YES"); } }
BZOJ2255 : [Swerc2010]Palindromic DNA