您的位置:首页 > Web前端 > JavaScript

【2-SAT(两次DFS版)】BZOJ1823-[JSOI2010]满汉全席

2016-07-10 23:04 411 查看
【题目大意】

有n个材料,m个评委。每种材料可以被用来做满族菜或汉族菜,m个评委有两种可以让他满意的猜中。问是否可以满足所有评委要求?

【思路】

每天只能做三道题,我已经是一个废人了……(葛优躺.jpg)

裸2-SAT,先写了个两遍DFS的,速度略慢……24ms?

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXN=200+50;
vector<int> E[MAXN];
vector<int> rE[MAXN];
vector<int> vs;
int cmp[MAXN],vis[MAXN];
int cnt,n,m;

void addedge(int u,int v)
{
E[u].push_back(v);
rE[v].push_back(u);
}

void dfs(int u)
{
vis[u]=1;
for (int i=0;i<E[u].size();i++)
{
int v=E[u][i];
if (!vis[v]) dfs(v);
}
vs.push_back(u);
}

void rdfs(int u,int t)
{
vis[u]=1;
cmp[u]=t;
for (int i=0;i<rE[u].size();i++)
{
int v=rE[u][i];
if (!vis[v]) rdfs(v,t);
}
}

void init()
{
for (int i=0;i<MAXN;i++) vector<int>().swap(E[i]);
for (int i=0;i<MAXN;i++) vector<int>().swap(rE[i]);
scanf("%d%d",&n,&m);
for (int i=0;i<m;i++)
{
char c1,c2;
int x,y,fx,fy;
getchar();
scanf("%c%d %c%d",&c1,&x,&c2,&y);
if (c1=='m') fx=x+n;else fx=x;
if (c2=='m') fy=y+n;else fy=y;
if (c1=='h') addedge(x+n,fy);else if (c1=='m') addedge(x,fy);
if (c2=='h') addedge(y+n,fx);else if (c1=='m') addedge(y,fx);
}
}

void solve()
{
memset(vis,0,sizeof(vis));
for (int i=1;i<=n;i++) if (!vis[i]) dfs(i);
memset(vis,0,sizeof(vis)),cnt=0;
for (int i=vs.size()-1;i>=0;i--)
if (!vis[vs[i]]) rdfs(vs[i],++cnt);
}

void get_ans()
{
for (int i=1;i<=n;i++)
if (cmp[i]==cmp[i+n])
{
puts("BAD");
return;
}
puts("GOOD");
}

int main()
{
int T;
scanf("%d",&T);
while (T--)
{
init();
solve();
get_ans();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: