• Codevs 1222 信与信封问题 二分图匹配,匈牙利算法


    题目: http://codevs.cn/problem/1222/

    1222 信与信封问题 

     

     时间限制: 1 s 
     空间限制: 128000 KB 
     题目等级 : 钻石 Diamond
     
     
    题目描述 Description

    John先生晚上写了n封信,并相应地写了n个信封将信装好,准备寄出。但是,第二天John的儿子Small John将这n封信都拿出了信封。不幸的是,Small John无法将拿出的信正确地装回信封中了。

    将Small John所提供的n封信依次编号为1,2,…,n;且n个信封也依次编号为1,2,…,n。假定Small John能提供一组信息:第i封信肯定不是装在信封j中。请编程帮助Small John,尽可能多地将信正确地装回信封。

    输入描述 Input Description

    n文件的第一行是一个整数n(n≤100)。信和信封依次编号为1,2,…,n。

    n接下来的各行中每行有2个数i和j,表示第i封信肯定不是装在第j个信封中。文件最后一行是2个0,表示结束。

    输出描述 Output Description

    输出文件的各行中每行有2个数i和j,表示第i封信肯定是装在第j个信封中。请按信的编号i从小到大顺序输出。若不能确定正确装入信封的任何信件,则输出“none”。

    样例输入 Sample Input

    3

    1  2

    1  3

    2  1

    0  0

    样例输出 Sample Output

    1   1

    数据范围及提示 Data Size & Hint
     

    分类标签 Tags 

    题解:

    二分图匹配+匈牙利算法

    先跑二分图,判断能匹配的个数,如果不足n个,直接输出无解。然后依次删除每一条匹配好的边,判断剩余的图中能否时这条被删的匹配边的两个端点连接,若不能找到增广路,则这条边时必须保留的,输出这条边。如果一条边都没有输出,则输出无解。

    程序中:

    BF[i] 为 第i个信封对应第BF[i]个信

    BF1[i] 为 第i个信对应第BF1[i]个信封

    f[i][j] 为 第i个信可能装到第j个信封中

    这道题要用BF1[]的原因是,题目要求按信的从小到大的顺序输出。每次删边时必须用BF1[]。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,BF[110],BF1[110];
     4 bool f[110][110];
     5 bitset<110> vis;
     6 int Xyl(int x)
     7 {
     8     int i;
     9     for(i=1;i<=n;i++)
    10     {
    11         if(f[x][i]==false&&vis[i]==0)
    12         {
    13             vis[i]=1;
    14             if(Xyl(BF[i])==1||BF[i]==0)//BF[i]为第i个信封对应第BF[i]个信,但f[i][j]为第i个信对应第j个信封,所以要存BF1[].
    15             {
    16                 BF[i]=x;
    17                 BF1[x]=i;
    18                 return 1;
    19             }
    20         }
    21     }
    22     return 0;
    23 }
    24 int main()
    25 {
    26     int i,ans,U,V,tmp,tmp1,pd=0;
    27     scanf("%d",&n);
    28     while(1)
    29     {
    30         scanf("%d %d",&U,&V);if(U==0&&V==0)break;
    31         f[U][V]=true;
    32     }
    33     ans=0;
    34     memset(BF,0,sizeof(BF));
    35     for(i=1;i<=n;i++)
    36     {
    37         vis.reset();
    38         ans+=Xyl(i);
    39     }
    40     if(ans!=n)printf("none");
    41     else
    42     {
    43         for(i=1;i<=n;i++)
    44         {
    45             //if(BF[i]!=0)
    46             {
    47                 V=BF1[i];
    48                 f[i][V]=true;
    49                 BF1[i]=0;BF[V]=0;
    50                 vis.reset();
    51                 if(Xyl(i)==0){printf("%d %d
    ",i,V);pd=1;BF1[i]=V;BF[V]=i;}
    52                 //BF[i]=tmp;
    53                 f[i][V]=false;
    54             }
    55         }
    56         if(pd==0)printf("none");
    57     }
    58     return 0;
    59 }
  • 相关阅读:
    去掉谷歌浏览器下input框自动填充的背景色
    ajax请求中动态显示问题
    Array对象的方法有
    请求页面的方法
    IE浏览器checkbox的样式问题
    property、classmethod和staticmethod总结
    面向对象和类
    内置函数补充map、reduce和filter等
    python实现控制台的进度条功能
    python常见内置函数
  • 原文地址:https://www.cnblogs.com/Var123/p/5395346.html
Copyright © 2020-2023  润新知