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

[BZOJ 1823][JSOI 2010]满汉全席(2-SAT入门题)

2015-03-14 11:36 323 查看

题目链接

http://www.lydsy.com/JudgeOnline/problem.php?id=1823

题目大意

虽然说这是个中文题,但是由于题目太长,我还是讲一下大意吧

一个厨艺比赛,主办方提供了nn种材料,厨师要将它们分别做成nn道菜,每道菜可以选择做成满式的,也可以做成汉式的,这个比赛有mm个评委,每个评委有两个喜好,比如说喜好满式羊肉、满式猪肉,或者是喜好满式牛肉、汉式羊肉等等。要想通过一个评委的审核,这个选手做的nn道菜里必须至少有一道菜(包括这道菜的风格)是这个评委所喜好的。问会不会出现一个选手做的nn道菜通过不了任何一个评委的审核。

思路

代码

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>

#define MAXE 51000
#define MAXV 5100

using namespace std;

int n,m;

inline int calc(int material,char type) //材料material做成风格为type的菜所对应的点编号
{
return material*2+(type=='m');
}

struct edge
{
int u,v,next;
}edges[MAXE];

int head[MAXV],nCount=0;

void AddEdge(int U,int V)
{
edges[++nCount].u=U;
edges[nCount].v=V;
edges[nCount].next=head[U];
head[U]=nCount;
}

int dfn[MAXV],low[MAXV],dfs_time=0;
bool inStack[MAXV];
int stack[MAXV],top=0;
int belong[MAXV],sccNum=0; //sccNum=强联通分量个数

void TarjanSCC(int u)
{
dfn[u]=low[u]=++dfs_time;
stack[++top]=u;
inStack[u]=true;
for(int p=head[u];p!=-1;p=edges[p].next)
{
int v=edges[p].v;
if(!dfn[v])
{
TarjanSCC(v);
low[u]=min(low[u],low[v]);
}
else if(inStack[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
sccNum++;
while(1)
{
int now=stack[top];
top--;
inStack[now]=false;
belong[now]=sccNum;
if(now==u) break;
}
}
}

int main()
{
int T;
scanf("%d",&T);
while(T--)
{
nCount=0;
sccNum=0;
dfs_time=0;
top=0;
memset(head,-1,sizeof(head));
memset(belong,0,sizeof(belong));
memset(inStack,false,sizeof(inStack));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int material1,material2;
char type1,type2;
getchar();
scanf("%c%d",&type1,&material1);
getchar();
scanf("%c%d",&type2,&material2);
int p1=calc(material1,type1),p2=calc(material2,type2);
AddEdge(p1^1,p2);
AddEdge(p2^1,p1);
}
for(int i=2;i<=(n<<1)+1;i++)
if(!dfn[i])
TarjanSCC(i);
bool flag=true;
for(int i=1;i<=n;i++)
if(belong[calc(i,'m')]==belong[calc(i,'h')])
{
flag=false;
break;
}
if(flag) printf("GOOD\n");
else printf("BAD\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: