CF 272E Dima and Horses(2-SAT变形)

题目大意:有n个点,每个点都最多有三个敌对点,要将这个n个点分成两组,而且每个组内的每个点,最多有一个敌对点和它在同一组里面。在第一组设为0, 第二组设为1;然后输出最后分配方案。

分析:以节点i为例, i有三个敌对点,如果i在0组,那么与i敌对的三个点中的两个就一定要在1组。给每个点赋值为1或0,然后使得所有节点都满足前述条件。很显然就是2-SAT问题。因为每个点虽多有3个敌对点,所以,总是有解的。

代码:

//E
//by Molly
#include <cstdio>
#define For(i, s, e ) for( int i = s; i < e; ++i ) 
#define N 300005

int n, m, d[N], E[N][5], g[N];
void Sat(int x) {
    int cnt = 0;
    For(i, 0, d[x]) if ( g[x] == g[E[x][i]] ) cnt++;
    //以下就是每个点如果不满足条件,那么就给它换组,dfs修改相关点,使得相关点满足条件
    if ( cnt >= 2 ) {
        g[x] ^= 1;
        For(i, 0, d[x]) if ( g[x] == g[E[x][i]] ) Sat( E[x][i] );
    }
}

int main()
{
    scanf("%d%d", &n, &m);
    For(i, 1, m+1) {
        int x, y;
        scanf("%d%d", &x, &y);
        E[x][d[x]++] = y;
        E[y][d[y]++] = x;
    }
    For(i, 1, n+1) Sat(i);
    For(i, 1, n+1) printf("%d", g[i]);
    printf("\n");
}


你可能感兴趣的:(CF 272E Dima and Horses(2-SAT变形))