满汉全席 (banquet)[JSOI2010]——2-Sat

题目描述
满汉全席是中国最丰盛的宴客菜肴,有许多种不同的材料透过满族或是汉族的料理方式,呈现在數量繁多的菜色之中。由于菜色众多而繁杂,只有极少數博学多闻技艺高超的厨师能够做出满汉全席,而能够烹饪出经过专家认证的满汉全席,也是中国厨师最大的荣誉之一。

世界满汉全席协会是由能够料理满汉全席的专家厨师们所组成,而他们之间还细分为许多不同等级的厨师。为了招收新进的厨师进入世界满汉全席协会,将于近日举办满汉全席大赛,协会派遣许多会员当作评审员,为的就是要在參赛的厨师之中,找到满汉料理界的明日之星。

大会的规则如下:每位參赛的选手可以得到 n 种材料,选手可以自由选择用满式或是汉式料理将材料当成菜肴。大会的评审制度是:共有 m 位评审员分别把关。每一位评审员对于满汉全席有各自独特的見解,但基本见解是,要有兩样菜色作为满汉全席的标志。如某评审认为,如果没有汉式东坡肉跟满式的涮羊肉锅,就不能算是满汉全席。但避免过于有主見的审核,大会规定一个评审员除非是在认为必备的两样菜色都没有做出來的狀况下,才能淘汰一位选手,否则不能淘汰一位參赛者。换句话說,只要參赛者能在这兩种材料的做法中,其中一个符合评审的喜好即可通过该评审的审查。如材料有猪肉,羊肉和牛肉时,有四位评审员的喜好如下表: 评审一 评审二 评审三 评审四 满式牛肉 满式猪肉 汉式牛肉 汉式牛肉 汉式猪肉 满式羊肉 汉式猪肉 满式羊肉 如參赛者甲做出满式猪肉,满式羊肉和满式牛肉料理,他将无法满足评审三的要求,无法通过评审。而參赛者乙做出汉式猪肉,满式羊肉和满式牛肉料理,就可以满足所有评审的要求。 但大会后來发现,在这样的制度下如果材料选择跟派出的评审员没有特别安排好的话,所有的參赛者最多只能通过部分评审员的审查而不是全部,所以可能会发生没有人通过考核的情形。

如有四个评审员喜好如下表时,则不論參赛者采取什么样的做法,都不可能通过所有评审的考核: 评审一 评审二 评审三 评审四 满式羊肉 满式猪肉 汉式羊肉 汉式羊肉 汉式猪肉 满式羊肉 汉式猪肉 满式猪肉 所以大会希望有人能写一个程序來判断,所选出的 m 位评审,会不会发生 没有人能通过考核的窘境,以便协会组织合适的评审团。

输入
第一行包含一个数字 K,代表测试文件包含了 K 组资料。

每一组测试资料的第一行包含兩个数字 n 跟 m(n≤100,m≤1000),代表有 n 种材料,m 位评审员。

为方便起見,材料舍弃中文名称而给予编号,编号分别从 1 到 n。

接下來的 m 行,每行都代表对应的评审员所拥有的兩个喜好,每个喜好由一个英文字母跟一个数字代表,

如 m1 代表这个评审喜欢第 1 个材料透过满式料理做出來的菜,

而 h2 代表这个评审员喜欢第 2 个材料透过汉式料理做出來的菜。

每个测试文件不会有超过 50 组测试资料,而每笔测试资料中材料的种类数跟评审员的个数均不超过 15。

输出
每笔测试资料输出一行,如果不会发生没有人能通过考核的窘境,输出 GOOD;否则输出 BAD(大写字母)。

样例输入
2
3 4
m3 h1
m1 m2
h1 h3
h3 m2
2 4
h1 m2
m2 m1
h1 h2
m1 h2
样例输出
GOOD
BAD

题解

标准的 2-Sat 问题
(A,B)不能同时不取
此时的连边方法是:A’与 B 连,B’与 A 连
然后 Tarjan 缩点判断 A 和 A’是否在一个连通块内即可

代码

#include<bits/stdc++.h>
#define N 205
using namespace std;
struct edge{int to,nex;}e[N*10];
int T,n,m,cnt,num,head[N],dfn[N],sta[N],vis[N],col[N],low[N],x,y;
char c1,c2;
void add(int s,int t){e[++cnt].to=t;e[cnt].nex=head[s];head[s]=cnt;}
void Tarjan(int x){
    dfn[x]=low[x]=++num;sta[++sta[0]]=x;vis[x]=1;
    for(int k=head[x];k;k=e[k].nex){
        if(!dfn[e[k].to]) Tarjan(e[k].to),low[x]=min(low[x],low[e[k].to]);
        else if(vis[e[k].to]) low[x]=min(low[x],dfn[e[k].to]);}
    if(dfn[x]==low[x]){
        col[x]=++col[0];vis[x]=0;
        while(sta[sta[0]]!=x)vis[sta[sta[0]]]=0,col[sta[sta[0]--]]=col[0];
        sta[0]--;}
}
int main(){
    cin>>T;
    while(T--){
        scanf("%d%d",&n,&m);
        for(int i=0;i<=N;i++) head[i]=dfn[i]=sta[i]=vis[i]=col[i]=col[i]=low[i]=0;
        cnt=num=0;
        for(int i=1;i<=m;i++){
            scanf(" %c%d %c%d",&c1,&x,&c2,&y);
            if(c1=='m') x+=n;
            if(c2=='m') y+=n;
            if(c1=='h') add(x+n,y); else add(x-n,y);
            if(c2=='h') add(y+n,x); else add(y-n,x);}
        for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i);
        bool pd=1;
        for(int i=1;i<=n*2;i++) if(col[i]&&col[i]==col[i+n]){pd=0;break;}
        puts(pd?"GOOD":"BAD");}
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来给你介绍一下如何实现。 首先,我们需要创建一个动态Web项目,然后在WebContent目录下创建index.jsp和login.jsp两个文件。 index.jsp中包含导航栏和跳转链接,代码如下: ``` <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>美食网站</title> </head> <body> <nav> <ul> <li><a href="nearby.jsp">附近美食</a></li> <li><a href="snacks.jsp">小吃快餐</a></li> <li><a href="drinks.jsp">饮品甜点</a></li> <li><a href="ranking.jsp">上榜好店</a></li> <li><a href="banquet.jsp">聚餐宴请</a></li> </ul> </nav> </body> </html> ``` 接着,我们需要创建nearby.jsp、snacks.jsp、drinks.jsp、ranking.jsp、banquet.jsp这五个页面,分别对应导航栏的五个选项。 以nearby.jsp为例,我们可以在页面中展示一些附近的美食店信息,代码如下: ``` <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>附近美食</title> </head> <body> <h1>附近美食</h1> <p>以下是附近的美食店信息:</p> <ul> <li>店名:xxx,地址:xxx</li> <li>店名:yyy,地址:yyy</li> <li>店名:zzz,地址:zzz</li> </ul> </body> </html> ``` 同样的,我们可以对其他四个页面进行类似的编写。 接着,我们来实现登录和注册功能。我们可以在login.jsp中添加一个表单,让用户输入用户名和密码,代码如下: ``` <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>登录</title> </head> <body> <h1>登录</h1> <form action="loginServlet" method="post"> <label for="username">用户名:</label> <input type="text" name="username" id="username"><br> <label for="password">密码:</label> <input type="password" name="password" id="password"><br> <input type="submit" value="登录"> </form> <p>还没有账号?<a href="register.jsp">点击注册</a></p> </body> </html> ``` 在表单中,我们将action设置为loginServlet,这是我们后面需要编写的Servlet类。当用户点击登录按钮时,表单数据会被提交到loginServlet中进行处理。 接着,我们来编写loginServlet类。我们可以在doPost方法中获取表单数据,并进行简单的校验,代码如下: ``` public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); if (username.equals("admin") && password.equals("123456")) { // 登录成功,将用户信息保存到Session中 HttpSession session = request.getSession(); session.setAttribute("username", username); // 跳转到首页 response.sendRedirect("index.jsp"); } else { // 登录失败,返回登录界面 response.sendRedirect("login.jsp"); } } } ``` 在这个Servlet类中,我们首先获取表单数据,然后进行简单的校验。如果用户名和密码都是admin和123456,就将用户信息保存到Session中,并跳转到首页。否则,就返回登录界面。 最后,我们还需要编写一个register.jsp页面,让用户进行注册。在这个页面中,我们可以添加一个表单,让用户输入用户名和密码,然后将数据提交到registerServlet中进行处理。 以上就是用JSP+Servlet设计一个美食网站的全部内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值