【CodeChef - VRTXCOVR 】Vertex Cover(2-SAT之构造解)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Coldfresh/article/details/83048112

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 ≤ 10^5
1 ≤ N ≤ 2 · 10^5
0 ≤ M ≤ 2 · 10^5
1 ≤ u, v ≤ N
1 ≤ sum of N over all test cases ≤ 10^6
1 ≤ sum of M over all test cases ≤ 10^6
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
Explanation
Example case 1: We can put nodes numbered 2 and 3 in set A and node 1 in set B. Note that this is a valid partition because set A is a vertex cover; also, nodes numbered 1 and 2 belong to different sets.

Example case 2: There exists no partition which satisfies the conditions.

把题意转化过来和上一题的套路是一样的,,,
代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#define maxn 200005
#define ll long long
#define mod 1000000007
#define INF 0x3f3f3f3f
using namespace std;
vector<int> g[maxn],_g[maxn];
int n,_n,m;
int dfn[maxn],low[maxn],_index;
bool inS[maxn];
int st[maxn],cnt;
int id[maxn],tot;
void tarjan(int u)
{
    dfn[u]=low[u]=++_index;
    st[++cnt]=u;inS[u]=true;
    for(int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if(!dfn[v])
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(inS[v])low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u])
    {
        int now;
        do
        {
            now=st[cnt--];
            inS[now]=false;
            id[now]=tot;
        }while(now!=u);
        ++tot;
    }
}
int opp[maxn];
int ind[maxn];
int color[maxn];
void topo()
{
    queue<int> que;
    for(int i=0;i<tot;i++)
        if(!ind[i])que.push(i);
    while(que.size())
    {
        int u=que.front();que.pop();
        if(!color[u])
        {
            color[u]=1;
            color[opp[u]]=2;
        }
        for(int i=0;i<_g[u].size();i++)
        {
            int v=_g[u][i];
            --ind[v];
            if(!ind[v])que.push(v);
        }
    }
}
void init()
{
    for(int i=0;i<n;i++)dfn[i]=0;_index=0;
    tot=0;
    for(int i=0;i<n;i++)ind[i]=0;
    for(int i=0;i<n;i++)color[i]=0;
    for(int i=0;i<=n;i++)g[i].clear(),_g[i].clear();
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        scanf("%d%d",&_n,&m);
        if(_n&1)n=_n+1;
        else n=_n;
        init();
        int x,y;
        while(m--)
        {
            scanf("%d%d",&x,&y);
            --x;--y;
            if(x!=(y^1))
            {
                g[x].push_back(y^1);
                g[y].push_back(x^1);
            }
        }
        for(int i=0;i<n;i++)
            if(!dfn[i])tarjan(i);
        bool sign=true;
        for(int i=0;i<n;i+=2)
        {
            if(id[i]==id[i+1])
            {
                sign=false;
                break;
            }
            else
            {
                opp[id[i]]=id[i+1];
                opp[id[i+1]]=id[i];
            }
        }
        if(!sign)
        {
            printf("impossible\n");
            continue;
        }
        printf("possible\n");
        for(int u=0;u<n;u++)
        {
            for(int i=0;i<g[u].size();i++)
            {
                int v=g[u][i];
                if(id[u]!=id[v])
                {
                    ++ind[id[u]];
                    _g[id[v]].push_back(id[u]);
                }
            }
        }
        topo();
        for(int i=0;i<_n;i++)
            if(color[id[i]]==1)printf("0");
            else printf("1");
        printf("\n");
    }
    return 0;
}
}

猜你喜欢

转载自blog.csdn.net/Coldfresh/article/details/83048112