BZOJ 1823 JSOI 2010 盛宴 2-SAT

标题效果:有着n材料的种类,m陪审团。

每种材料具有两种不同的方法。每个法官都有两个标准。做出来的每一个法官的菜必须至少满足一个需求。

问:是否有这样一个程序。


思考:2-SAT经典的内置图形问题。因为每种材料只能有两种方法,约束条件通常就想到2-SAT。每个评委必须至少满足一种。这就是建图的条件。

所以连边A‘ -> B

      B’ -> A

这样表示的是假设A不能满足某个评委,那么就必须让b满足这个评委。

然后就是Tarjan缩点,推断是否有个菜品的两种做法在一个scc中,若有就是无解,没有就是有解。


CDOE:


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 5010
using namespace std;

int cases;
int points,cnt;

int head[MAX],_total;
int _next[MAX],aim[MAX];

int dfn[MAX],low[MAX],total;
int stack[MAX],top;
bool in_stack[MAX];
int changed[MAX],scc;

char c1,c2;

inline void Initialize();
inline void Add(int x,int y);
void Tarjan(int x);

int main()
{
    for(cin >> cases;cases; --cases) {
        scanf("%d%d",&points,&cnt);
        Initialize();
        for(int x,y,i = 1;i <= cnt; ++i) {
            getchar();
            scanf("%c%d %c%d",&c1,&x,&c2,&y);
            x = (x << 1) + (c1 == 'h');
            y = (y << 1) + (c2 == 'h');
            Add(x^1,y);
            Add(y^1,x); 
        }
        for(int i = 2;i <= (points << 1|1); ++i)
            if(!dfn[i]) Tarjan(i);
        bool flag = true;
        for(int i = 1;i <= points; ++i)
        	if(changed[i << 1] == changed[i << 1|1])
        		flag = false;
    	if(flag)	puts("GOOD");
    	else		puts("BAD");
    }
    return 0;
}

inline void Initialize()
{
	total = _total = top = scc =0;
	memset(dfn,0,sizeof(dfn));
	memset(head,0,sizeof(head));
	memset(in_stack,false,sizeof(in_stack));
}

inline void Add(int x,int y)
{
    _next[++_total] = head[x];
    aim[_total] = y;
    head[x] = _total;
}

void Tarjan(int x)
{
    dfn[x] = low[x] = ++total;
    stack[++top] = x;
    in_stack[x] = true;
    for(int i = head[x];i;i = _next[i]) {
        if(!dfn[aim[i]])
            Tarjan(aim[i]),low[x] = min(low[x],low[aim[i]]);
        else if(in_stack[aim[i]])
        	low[x] = min(low[x],dfn[aim[i]]);
    }
    if(low[x] == dfn[x]) {
    	scc++;
    	int temp;
    	do {
    		temp = stack[top--];
    		changed[temp] = scc;
    		in_stack[temp] = false;
    	}while(temp != x);
    }
}


版权声明:本文博主原创文章,博客,未经同意不得转载。

posted @ 2015-10-13 21:07  phlsheji  阅读(146)  评论(0编辑  收藏  举报