zoukankan      html  css  js  c++  java
  • codevs 1222 信与信封问题(二分图的完美匹配)

    1222 信与信封问题

     

     
    题目描述 Description

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

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

    输入描述 Input Description

    n文件的第一行是一个整数nn100)。信和信封依次编号为12,…,n

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

    输出描述 Output Description

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

    样例输入 Sample Input

    3

    1  2

    1  3

    2  1

    0  0

    样例输出 Sample Output

    1   1

    【思路】

           二分图的完美匹配。

           先一遍match看是否有能够完美匹配,没有则none。如果有枚举删除完美匹配中的边,如果删边后该点不能匹配则输出该边,如果没有则none。


     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 #include<vector>
     5 #define FOR(a,b,c) for(int a=(b);a<(c);a++)
     6 using namespace std;
     7 
     8 const int maxn = 100+10;
     9 
    10 bool T[maxn];
    11 int lkx[maxn],lky[maxn];
    12 //lkx 表示与X结点匹配的Y结点 lky表示与Y结点相匹配的X结点 
    13 int n,m;
    14 int A[maxn][maxn];
    15 
    16 bool match(int u) {
    17     for(int v=1;v<=n;v++)
    18         if(!A[u][v] && !T[v]) {
    19             T[v]=1;
    20             if(!lky[v] || match(lky[v])) {
    21                 lky[v]=u , lkx[u]=v;
    22                 return true;
    23             }
    24         }
    25     return false;
    26 }
    27 
    28 int main() {
    29     scanf("%d",&n);
    30     int u,v;
    31     while(scanf("%d%d",&u,&v)==2 && (u&&v))
    32         A[u][v]=1;
    33     int ans=0;
    34     for(int i=1;i<=n;i++) {
    35         memset(T,0,sizeof(T));
    36         if(match(i)) ans++;
    37     }
    38     if(ans!=n) printf("none
    ");
    39     else {
    40         bool flag=0;
    41         for(int i=1;i<=n;i++) {
    42             int v=lkx[i];
    43             A[i][v]=1; 
    44             lkx[i]=0 , lky[v]=0;
    45             memset(T,0,sizeof(T));
    46             if(!match(i)) {
    47                 printf("%d %d
    ",i,v);
    48                 lkx[i]=v,lky[v]=i; flag=1;    //恢复 
    49             }
    50             A[i][v]=0;                        //恢复 
    51         }
    52         if(!flag) puts("none
    ");
    53     }
    54     return 0;
    55 }
  • 相关阅读:
    VB.NET中对象的克隆 利用了内存流内象和序列化
    关于对象组件编写的一点想法
    虽然有人说什么和平第一, 经济第一, 可是我怎么能不因为愤怒而发抖?
    用C# 调用MS speech引擎, 让电脑读文本, 或是存到WAV文件里去.
    抽空看了一下 dockpanel suite, 知道如何用了, 立此存照
    dn081A
    如何列出某类型的所有成员
    上周买了毛爷爷传
    【转载】MySQL双主双从高可用集群架构
    【转载】MySQL和Keepalived高可用双主复制
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5076768.html
Copyright © 2011-2022 走看看