zoukankan      html  css  js  c++  java
  • [HNOI2006]超级英雄

    题目描述

    现在电视台有一种节目叫做超级英雄,大概的流程就是每位选手到台上回答主持人的几个问题,然后根据回答问题的多少获得不同数目的奖品或奖金。主持人问题准备了若干道题目,只有当选手正确回答一道题后,才能进入下一题,否则就被淘汰。为了增加节目的趣味性并适当降低难度,主持人总提供给选手几个“锦囊妙计”,比如求助现场观众,或者去掉若干个错误答案(选择题)等等。

    这里,我们把规则稍微改变一下。假设主持人总共有m道题,选手有n种不同的“锦囊妙计”。主持人规定,每道题都可以从两种“锦囊妙计”中选择一种,而每种“锦囊妙计”只能用一次。我们又假设一道题使用了它允许的锦囊妙计后,就一定能正确回答,顺利进入下一题。现在我来到了节目现场,可是我实在是太笨了,以至于一道题也不会做,每道题只好借助使用“锦囊妙计”来通过。如果我事先就知道了每道题能够使用哪两种“锦囊妙计”,那么你能告诉我怎样选择才能通过最多的题数吗?

    输入输出格式

    输入格式:

    输入的第一行是两个正整数  和  ()表示总共有 n 种“锦囊妙计”,编号为 ,总共有  个问题。

    以下的m行,每行两个数,分别表示第  个问题可以使用的“锦囊妙计”的编号。

    注意,每种编号的“锦囊妙计”只能使用一次,同一个问题的两个“锦囊妙计”可能一样。

    输出格式:

    输出的第一行为最多能通过的题数 ,接下来  行,每行为一个整数,第  行表示第  题使用的“锦囊妙计的编号”。

    如果有多种答案,那么任意输出一种,本题使用 Special Judge 评判答案。

    输入输出样例

    输入样例#1:
    5 6
    3 2
    2 0
    0 3
    0 4
    3 2
    3 2
    输出样例#1:
    4
    3
    2
    0
    4

    题解:

    1.Solution1 二分图匹配

    可以直接上匈牙利,枚举每一个问题,直到匹配失败时的问题数就是答案

    原理可以认为是匈牙利算法不会使之前的问题失去匹配,而是更改它的匹配对象.

    2.Solution2 二分答案+网络流

    直接二分mid,将前mid个问题建立匹配,判断最大流是否等于mid即可

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 using namespace std;
     8 const int N=2005;
     9 int head[N],num=0;
    10 struct Lin{
    11     int next,to;
    12 }a[N<<1];
    13 void init(int x,int y){
    14     a[++num].next=head[x];
    15     a[num].to=y;
    16     head[x]=num;
    17 }
    18 void addedge(int x,int y){
    19     init(x,y);init(y,x);
    20 }
    21 int n,m,bel[N];bool vis[N];
    22 bool dfs(int x){
    23     int u;
    24     for(int i=head[x];i;i=a[i].next){
    25         u=a[i].to;
    26         if(!vis[u]){
    27             vis[u]=true;
    28             if(!bel[u] || dfs(bel[u])){
    29                 bel[x]=u;bel[u]=x;return true;
    30             }
    31         }
    32     }
    33     return false;
    34 }
    35 void work(){
    36     int x,y;
    37     scanf("%d%d",&n,&m);
    38     for(int i=1;i<=m;i++){
    39         scanf("%d%d",&x,&y);
    40         addedge(i,x+m);addedge(i,y+m);
    41     }
    42     bool t;int i;
    43     for(i=1;i<=m;i++){
    44         memset(vis,0,sizeof(vis));
    45         t=dfs(i);
    46         if(!t)break;
    47     }
    48     i--;
    49      printf("%d
    ",i);
    50     for(int j=1;j<=i;j++)
    51       printf("%d
    ",bel[j]-m);
    52 }
    53 int main()
    54 {
    55     work();
    56     return 0;
    57 }
  • 相关阅读:
    swfupload控件文件上传大小限制设置
    C# 判断和创建目录路径
    [转载]Python ImportError: No module named 'requests'解决方法
    使用SQL语句进行特定值排序
    使用SQL语句进行数据复制
    Email正则表达式验证
    c#winform程序的改名(修改名称)
    关于无法加载DLL"***.dll":找不到指定的模块(异常来自HRESULT:0x8007007E)问题的解决办法
    C#中倒计时汇总
    C#中倒计时
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7214227.html
Copyright © 2011-2022 走看看