• POJ 1719 二分图最大匹配(记录路径)


    Shooting Contest
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 4097   Accepted: 1499   Special Judge

    Description

    Welcome to the Annual Byteland Shooting Contest. Each competitor will shoot to a target which is a rectangular grid. The target consists of r*c squares located in r rows and c columns. The squares are coloured white or black. There are exactly two white squares and r-2 black squares in each column. Rows are consecutively labelled 1,..,r from top to bottom and columns are labelled 1,..,c from left to right. The shooter has c shots. 

    A volley of c shots is correct if exactly one white square is hit in each column and there is no row without white square being hit. Help the shooter to find a correct volley of hits if such a volley exists. 
    Example 
    Consider the following target: 

    Volley of hits at white squares in rows 2, 3, 1, 4 in consecutive columns 1, 2, 3, 4 is correct. 
    Write a program that: verifies whether any correct volley of hits exists and if so, finds one of them.

    Input

    The first line of the input contains the number of data blocks x, 1 <= x <= 5. The following lines constitute x blocks. The first block starts in the second line of the input file; each next block starts directly after the previous one. 

    The first line of each block contains two integers r and c separated by a single space, 2 <= r <= c <= 1000. These are the numbers of rows and columns, respectively. Each of the next c lines in the block contains two integers separated by a single space. The integers in the input line i + 1 in the block, 1 <= i <= c, are labels of rows with white squares in the i-th column. 

    Output

    For the i-th block, 1 <= i <= x, your program should write to the i-th line of the standard output either a sequence of c row labels (separated by single spaces) forming a correct volley of hits at white squares in consecutive columns 1, 2, ..., c, or one word NO if such a volley does not exists.

    Sample Input

    2
    4 4
    2 4
    3 4
    1 3
    1 4
    5 5
    1 5
    2 4
    3 4
    2 4
    2 3
    

    Sample Output

    2 3 1 4
    NO
    

    Source

     
    题目意思:
    有n*m的格子,每个格子要么是白色要么是黑色。题目给定每列有2个白色的格子,其他的格子为黑色。每列选出一个白色的格子,使得每一行至少有一个白色格子被选出,若能满足条件则输出每列选出白色格子的行数,否则输出NO。
     
    思路:
    列标号放在左边,行标号放在右边,若该列a可选择第b行和第c行,则a-b连边,a-c连边。
    在增广过程中记录to[i]和from[j]即第i列选择的行的标号和第j行被选择的列的标号。
    init:to 0;from -1
    1、若n>m,一定不可满足条件
    2、若增广结束后存在from[i]=-1,则第i行一定不能被选择,输出NO
    3、若增广结束后存在to[i]=0,那么第i列选择a和b其中一个即可。
     
    代码:
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 #include <vector>
     6 #include <queue>
     7 #include <cmath>
     8 #include <set>
     9 using namespace std;
    10 
    11 #define N 1005
    12 #define inf 999999999
    13 
    14 int max(int x,int y){return x>y?x:y;}
    15 int min(int x,int y){return x<y?x:y;}
    16 int abs(int x,int y){return x<0?-x:x;}
    17 
    18 int from[N];
    19 int to[N];
    20 bool visited[N];
    21 int n, m;
    22 vector<int>ve[N];
    23 
    24 int march(int u){
    25     int i, v;
    26     for(i=0;i<ve[u].size();i++){
    27         v=ve[u][i];
    28         if(!visited[v]){
    29             visited[v]=true;
    30             if(from[v]==-1||march(from[v])){
    31                 from[v]=u;
    32                 to[u]=v;
    33                 return 1;
    34             }
    35         }
    36     }
    37     return 0;
    38 }
    39 
    40 main()
    41 {
    42     int t, i, j, k, u, v;
    43     cin>>t;
    44     while(t--){
    45         scanf("%d %d",&n,&m);
    46         for(i=0;i<=m;i++) ve[i].clear();
    47         for(i=1;i<=m;i++){
    48             scanf("%d %d",&u,&v);
    49             ve[i].push_back(u);
    50             ve[i].push_back(v);
    51         }
    52         if(n>m) {
    53             printf("NO
    ");continue;
    54         }
    55         memset(from,-1,sizeof(from));
    56         int num=0;
    57         for(i=1;i<=m;i++){
    58             memset(visited,false,sizeof(visited));
    59             march(i);
    60         }
    61         int f=1;
    62         for(i=1;i<=n;i++){
    63             if(from[i]==-1){
    64                 f=0;break;
    65             }
    66         }
    67         if(!f){
    68             printf("NO
    ");continue;
    69         }
    70         for(i=1;i<=m;i++){
    71             if(!to[i]){
    72                 to[i]=ve[i][0];
    73             }
    74         }
    75         printf("%d",to[1]);
    76         for(i=2;i<=m;i++) printf(" %d",to[i]);
    77         cout<<endl;
    78     }
    79 }
  • 相关阅读:
    10个最常见的 HTML5 面试题及答案
    YII 的源码分析(-)
    架构师速成5.2-如何掌握综合性技能 分类: 架构师速成 2015-06-30 11:18 405人阅读 评论(0) 收藏
    架构师速成5.1-小学gtd进阶 分类: 架构师速成 2015-06-26 21:17 313人阅读 评论(0) 收藏
    架构师速成4.3-幼儿园要学会查找资料 分类: 架构师速成 2015-06-25 09:08 409人阅读 评论(0) 收藏
    架构师速成4.2-幼儿园要学会如何高效学习 分类: 架构师速成 2015-06-24 09:10 409人阅读 评论(2) 收藏
    架构师速成4.1-幼儿园要学会如何学习(转载自36氪) 分类: 架构师速成 2015-06-24 09:05 114人阅读 评论(0) 收藏
    架构师速成-目录 分类: 架构师速成 2015-06-21 20:48 146人阅读 评论(0) 收藏
    架构师速成7-高中 分类: 架构师速成 2015-06-21 19:17 132人阅读 评论(0) 收藏
    架构师速成6-初中 分类: 架构师速成 2015-06-20 12:08 149人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/qq1012662902/p/4639005.html
Copyright © 2020-2023  润新知