All submissions for this problem are available.
You are given an undirected graph G = (V, E) containing N nodes and M edges. The nodes are numbered from 1 to N. A subset C of V is a vertex cover if for every edge (u, v) ∈ E, at least one of u and v belong to C. Note that C = V is always a vertex cover.
Consider a partition of V into two sets A and B. It is said to be a valid partition, if the following two conditions are satisfied: A should be a vertex cover. And for each i such that 1 ≤ i ≤ n/2, nodes 2i and 2i - 1 don’t belong to the same set (i.e. one belongs to set A and the other to set B).
Determine if a valid partition exists. If it exists, provide an example of one valid partition.
Input
The first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows.
The first line of each test case contains two space-separated integers N and M denoting the number of nodes and number of edges in the graph respectively.
Each of the following M lines contains two space-separated integers u and v denoting an edge between nodes u and v.
Output
For each test case, print a line containing the string “possible” (without quotes) if a solution exists or “impossible” otherwise.
If a solution exists, print a second line containing a binary string. The i-th character of this string should be ‘0’ if vertex i is in set B or ‘1’ if it is in set A.
Constraints
1 ≤ T ≤ 105
1 ≤ N ≤ 2 · 105
0 ≤ M ≤ 2 · 105
1 ≤ u, v ≤ N
1 ≤ sum of N over all test cases ≤ 106
1 ≤ sum of M over all test cases ≤ 106
Example
Input:
2
3 2
1 2
2 3
4 5
1 3
2 4
1 4
1 2
2 3
Output:
possible
011
impossible
题意:给出一个图,把这些点分别标记0或1,满足第2n和第2n-1个点不同,并且有边相连的两个点不能同时为0,问是否有种方案可以满足.
思路:2-SAT模型,不知道就只能瞎搞了。。
把2n-1和2n看成一组,按照题目给出的边,建边方式如下:
模型一:两者(A,B)不能同时取
那么选择了A就只能选择B’,选择了B就只能选择A’
连边A→B’,B→A’
模型二:两者(A,B)不能同时不取
那么选择了A’就只能选择B,选择了B’就只能选择A
连边A’→B,B’→A
模型三:两者(A,B)要么都取,要么都不取
那么选择了A,就只能选择B,选择了B就只能选择A,选择了A’就只能选择B’,选择了B’就只能选择A’
连边A→B,B→A,A’→B’,B’→A’
模型四:两者(A,A’)必取A
连边A’→A
详见:https://blog.csdn.net/moguxiaozhe/article/details/49047085
所以题目给出的边是模型二:(A,B)不能同时取.
然后按照模板跑一下即可.
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 200000
#define MAXM 200000
#define mem(a,b) memset(a,b,sizeof(a))
int n,m;
struct node
{
int v;
node *next;
};
node edge[MAXM*2];
node *cnt=&edge[0];
node *adj[MAXN];
node edge2[MAXM*2];
node *cnt2=&edge2[0];
node *adj2[MAXN];
int dfn[MAXN],low[MAXN],dcnt;
int stack[MAXN],top;
int Belong[MAXN],Num[MAXN],opp[MAXN],scc;
int In[MAXN],q[MAXN],col[MAXN];
bool Instack[MAXN],ans[MAXN];
inline void Get_int(int &Ret)
{
char ch;
bool flag=false;
for(;ch=getchar(),ch<'0'||ch>'9';)
if(ch=='-')
flag=true;
for(Ret=ch-'0';ch=getchar(),ch>='0'&&ch<='9';Ret=Ret*10+ch-'0');
flag&&(Ret=-Ret);
}
inline int Get(int x)
{
if(x%2)
return x+1;
return x-1;
}
inline void Addedge(int u,int v)
{
node *p=++cnt;
p->v=v;
p->next=adj[u];
adj[u]=p;
}
inline void Addedge2(int u,int v)
{
node *p=++cnt2;
p->v=v;
p->next=adj2[u];
adj2[u]=p;
}
void Read()
{
Get_int(n);
Get_int(m);
int i,j,k;
for(int i = 0;i<= n+n;i++)
{
dfn[i]=low[i]= stack[i]=Belong[i] = Num[i] =opp[i] = In[i]= q[i]= col[i]=Instack[i] = ans[i] = 0;
adj[i] = adj2[i] = NULL;
}
cnt=&edge[0];
cnt2=&edge2[0];
for(i=1;i<=m;i++)
{
Get_int(j);
Get_int(k);
Addedge(Get(j),k);
Addedge(Get(k),j);
}
}
void Tarjan(int u)
{
int v;
dfn[u]=low[u]=++dcnt;
stack[++top]=u;
Instack[u]=true;
for(node *p=adj[u];p;p=p->next)
{
v=p->v;
if(!dfn[v])
{
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(Instack[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
scc++;
do
{
v=stack[top];
top--;
Instack[v]=false;
Belong[v]=scc;
Num[scc]++;
}while(v!=u);
}
}
bool Work()
{
int i;
for(i=1;i<=n;i++)
if(!dfn[i])
Tarjan(i);
for(i=1;i<=n;i+= 2)
{
if(Belong[i]==Belong[i+1])
return false;
opp[Belong[i]]=Belong[i+1];
opp[Belong[i+1]]=Belong[i];
}
int u,v;
for(i=1;i<=n;i++)
for(node *p=adj[i];p;p=p->next)
{
v=p->v;
if(Belong[i]!=Belong[v])
{
Addedge2(Belong[v],Belong[i]);
In[Belong[i]]++;
}
}
int l=0,r=0;
for(i=1;i<=scc;i++)
if(!In[i])
{
q[r]=i;
r++;
}
while(l<r)
{
u=q[l];
l++;
if(!col[u])
{
col[u]=1;
col[opp[u]]=-1;
}
for(node *p=adj2[u];p;p=p->next)
{
v=p->v;
In[v]--;
if(!In[v])
{
q[r]=v;
r++;
}
}
}
for(i=1;i<=n;i+= 2)
if(col[Belong[i]]==1)
ans[i]=true;
return true;
}
void Print()
{
if(Work())
{
printf("possible\n");
int i;
for(i=1;i<=n;i+= 2)
{
if(i == n)
{
printf("1");
break;
}
if(ans[i])
printf("10");
else
printf("01");
}
printf("\n");
}
else
printf("impossible\n");
}
int main()
{
int t;
cin>>t;
while(t--)
{
dcnt = scc = top = 0;
Read();
Print();
}
return 0;
}