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 }
  • 相关阅读:
    606. Construct String from Binary Tree 【easy】
    520. Detect Capital【easy】
    28. Implement strStr()【easy】
    521. Longest Uncommon Subsequence I【easy】
    线程,进程,任务
    nginx for windows中的一项缺陷
    nginx在windwos中的使用
    关于wxwidgets图形界面的关闭窗口的按钮无效的解决办法
    进程与线程之间的资源的关系
    关于函数可重入需要满足的条件
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5076768.html
Copyright © 2011-2022 走看看