【bzoj 3495】PA2010 Riddle

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)$ .

 

 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 }
View Code

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324890239&siteId=291194637