Description
There are n towns divided into k counties, and there are m undirected edges connecting the towns. It is required to choose a town as the capital for each county, so that at least one endpoint of each edge is the capital.
Input
The first line has three integers, the number of towns n (1<=n<=10^6), the number of sides m (0<=m<=10^6), and the number of counties k (1<=k<=n).
Next m lines, each line has two integers ai and bi (ai≠bi), indicating that there is an undirected edge connecting the towns ai and bi.
Next k lines, the jth line begins with an integer wj, followed by wj integers, representing the towns contained in the jth county.
Output
If there is a solution, output TAK, otherwise output NIE.
Each point $x$ is split into two pairs of points, $x$ represents choosing $x$ as the capital, $x+n$ means not choosing $x$ as the capital, $x+2n$ means the prefix of $x$ has been included Capital, $x+3n$ means the prefix of $x$ does not contain the capital.
For each undirected edge $(x,y)$ in the original graph , because at least one endpoint is the capital, connecting edges $(x+n,y)$ , $(y+n,x)$ .
For each point $x$ , connect the edges $(x,x+2n)$ , $(x+3n,x+n)$ .
For each point $x$ and its previous point $last$ , the edges are connected as follows: $(last+2n,x+2n)$ , $(x+3n,last+3n)$ , $(last+ 2n,x+n)$ , $(x,last+3n)$ .
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define LL long long 5 using namespace std; 6 const int N=4e6+5; 7 int n,m,k,cnt,x,y,last,tim,top,color; 8 int first[N],dfn[N],low[N],sta[N],c[N]; 9 bool vis[N]; 10 struct edge{int to,next;}e[N*3]; 11 void ins(int u,int v){e[++cnt]=(edge){v,first[u]};first[u]=cnt;} 12 int read() 13 { 14 int x=0,f=1;char c=getchar(); 15 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 16 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 17 return x*f; 18 } 19 void tarjan(int x) 20 { 21 low[x]=dfn[x]=++tim; 22 sta[++top]=x;vis[x]=true; 23 for(int i=first[x];i;i=e[i].next) 24 { 25 int to=e[i].to; 26 if(!dfn[to])tarjan(to),low[x]=min(low[x],low[to]=min(low[x],low[to])); 27 else if(vis[to])low[x]=min(low[x],dfn[to]); 28 } 29 if(low[x]==dfn[x]) 30 { 31 color++; 32 while(sta[top]!=x)vis[sta[top]]=false,c[sta[top--]]=color; 33 vis[x]=false;c[x]=color;top--; 34 } 35 } 36 bool check() 37 { 38 for(int i=1;i<=n;i++) 39 if(c[i]==c[i+n]||c[i+2*n]==c[i+3*n])return false; 40 return true; 41 } 42 int main() 43 { 44 n=read();m=read();k=read(); 45 for(int i=1;i<=m;i++) 46 { 47 x=read();y=read(); 48 ins(x+n,y);ins(y+n,x); 49 } 50 for(int i=1;i<=k;i++) 51 { 52 x=read();last=0; 53 for(int j=1;j<=x;j++) 54 { 55 y=read(); 56 ins(y,y+2*n);ins(y+3*n,y+n); 57 if(last) 58 { 59 ins(last+2*n,y+2*n); 60 ins(y+3*n,last+3*n); 61 ins(last+2*n,y+n); 62 ins(y,last+3*n); 63 } 64 last=y; 65 } 66 } 67 for(int i=1;i<=4*n;i++)if(!dfn[i])tarjan(i); 68 if(check())printf("TAK"); 69 else printf("NIE"); 70 return 0; 71 }