卧薪尝胆,厚积薄发。
JSOI2010 满汉全席
Date: Mon Jul 09 21:09:58 CST 2018 In Category: NoCategory

Description:

$n$ 道菜,每道菜有两种做法, $m$ 个限制,要求第 $k_1$ 道菜为第 $c_1$ 种做法或第 $k_2$ 道菜为 $c_2$ 种做法,问能否满足所有人。
$1\le n \le 100$ $ 1\le m \le 1000$ $ 1\le T \le 50$

Solution:

如果第 $k_1$ 道菜没选第 $c_1$ 种做法,则第 $k_2$ 道菜必须选第 $c_2$ 种做法,用 $2-SAT$ 判断即可。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<stack>
#include<cstring>
using namespace std;
int testcases;
int n,m;
#define MAXN 110
#define MAXM 1010
struct edge
{
int to,nxt;
}e[(MAXM * 2) << 1];
int edgenum = 0;
int lin[MAXN << 2] = {0};
void add(int a,int b)
{
++edgenum;e[edgenum].to = b;e[edgenum].nxt = lin[a];lin[a] = edgenum;
return;
}
stack<int> s;
int dfn[MAXN << 1],low[MAXN << 1],tot = 0;
bool v[MAXN << 1];
int scc = 0,ins[MAXN << 1];
void tarjan(int k)
{
dfn[k] = low[k] = ++tot;
v[k] = true;s.push(k);
for(int i = lin[k];i != 0;i = e[i].nxt)
{
if(dfn[e[i].to] == 0)
{
tarjan(e[i].to);
low[k] = min(low[k],low[e[i].to]);
}
else if(v[e[i].to])
{
low[k] = min(low[k],dfn[e[i].to]);
}
}
if(low[k] == dfn[k])
{
int t;
++scc;
do
{
t = s.top();s.pop();
v[t] = false;ins[t] = scc;
}while(t != k);
}
return;
}
char getc()
{
char c = getchar();
while(c != 'h' && c != 'm')c = getchar();
return c;
}
int read()
{
int res = 0;
char c = getchar();
while(!isdigit(c))c = getchar();
while(isdigit(c))
{
res = (res << 1) + (res << 3) + c - '0';
c = getchar();
}
return res;
}
void work()
{
memset(lin,0,sizeof(lin));
edgenum = 0;
tot = 0;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(ins,0,sizeof(ins));
memset(v,0,sizeof(v));
scc = 0;
scanf("%d%d",&n,&m);
int k1,k2,type1,type2;
for(int i = 1;i <= m;++i)
{
type1 = (getc() == 'h' ? 0 : 1);
k1 = read();
type2 = (getc() == 'h' ? 0 : 1);
k2 = read();
add((k1 - 1) * 2 + (type1 ^ 1),(k2 - 1) * 2 + type2);
add((k2 - 1) * 2 + (type2 ^ 1),(k1 - 1) * 2 + type1);
}
for(int i = 0;i < 2 * n;++i)
{
if(dfn[i] == 0)
{
tarjan(i);
}
}
bool found = false;
for(int i = 1;i <= n;++i)
{
if(ins[(i - 1) * 2 + 1] == ins[(i - 1) * 2 + 0])
{
found = true;
break;
}
}
if(found)puts("BAD");
else puts("GOOD");
return;
}
int main()
{
scanf("%d",&testcases);
for(int i = 1;i <= testcases;++i)
work();
return 0;
}
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡