明显的2-SAT模型,但是对于国家的限制,边数是
O(n2)
的。
可以考虑对有x个城市的国家新建x个结点,第i个结点表示1~i的结点中是否存在首都。那么边数就可以优化到
O(n)
了
#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 1000010
#define M 5000100
using namespace std;
int n,m,k,cnt,g,tms;
int A[N],B[N];
int G[M],flg[M],low[M],dfn[M],vis[M],stk[M],top;
struct edge{
int t,nx;
}E[M<<2];
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void rea(int &x){
char c=nc(); x=0;
for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
inline void Insert(int x,int y){
E[++cnt].t=y; E[cnt].nx=G[x]; G[x]=cnt;
}
void tarjan(int x){
dfn[x]=low[x]=++tms;
stk[++top]=x;
vis[x]=1;
for(int i=G[x];i;i=E[i].nx)
if(!vis[E[i].t]) tarjan(E[i].t),low[x]=min(low[x],low[E[i].t]);
else if(vis[E[i].t]==1) low[x]=min(low[x],dfn[E[i].t]);
if(low[x]==dfn[x]){
++*flg;
while(1){
int u=stk[top]; top--;
flg[u]=*flg;
vis[u]=2;
if(u==x||!top) break;
}
}
}
int main(){
rea(n); rea(m); rea(k); g=n;
for(int i=1;i<=m;i++){
int x,y; rea(x); rea(y);
Insert(x<<1|1,y<<1);
Insert(y<<1|1,x<<1);
}
for(int i=1;i<=k;i++){
int t; rea(t);
for(int j=1;j<=t;j++) rea(A[j]),B[j]=++g;
for(int j=1;j<t;j++) Insert(B[j]<<1,B[j+1]<<1);
for(int j=2;j<=t;j++) Insert(B[j]<<1|1,B[j-1]<<1|1),Insert(B[j-1]<<1,A[j]<<1|1),Insert(A[j]<<1,B[j-1]<<1|1);
for(int j=1;j<=t;j++) Insert(A[j]<<1,B[j]<<1),Insert(B[j]<<1|1,A[j]<<1|1);
}
for(int i=2;i<=(g<<1|1);i++)
if(!vis[i]) tarjan(i);
for(int i=1;i<=g;i++)
if(flg[i<<1]==flg[i<<1|1]) return puts("NIE"),0;
return puts("TAK"),0;
}