zoukankan      html  css  js  c++  java
  • HDU2819(KB10-E 二分图最大匹配)

    Swap

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 3800    Accepted Submission(s): 1401
    Special Judge


    Problem Description

    Given an N*N matrix with each entry equal to 0 or 1. You can swap any two rows or any two columns. Can you find a way to make all the diagonal entries equal to 1?
     

    Input

    There are several test cases in the input. The first line of each test case is an integer N (1 <= N <= 100). Then N lines follow, each contains N numbers (0 or 1), separating by space, indicating the N*N matrix.
     

    Output

    For each test case, the first line contain the number of swaps M. Then M lines follow, whose format is “R a b” or “C a b”, indicating swapping the row a and row b, or swapping the column a and column b. (1 <= a, b <= N). Any correct answer will be accepted, but M should be more than 1000.

    If it is impossible to make all the diagonal entries equal to 1, output only one one containing “-1”. 
     

    Sample Input

    2 0 1 1 0 2 1 0 1 0
     

    Sample Output

    1 R 1 2 -1
     

     

    Source

     
    按行交换。对行进行1-n编号,对列也进行编号。
    若第i行的第j1、j2……列有1,则节点i与j1、j2……连边。
    二分图跑最大匹配,为完美匹配方可。
    matching数组保存每个点的匹配,模拟一下交换输出答案。
      1 //2017-08-26
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <iostream>
      5 #include <algorithm>
      6 
      7 using namespace std;
      8 
      9 const int N = 100000;
     10 const int M = 5000000;
     11 int head[N], tot;
     12 struct Edge{
     13     int to, next;
     14 }edge[M];
     15 
     16 void init(){
     17     tot = 0;
     18     memset(head, -1, sizeof(head));
     19 }
     20 
     21 void add_edge(int u, int v){
     22     edge[tot].to = v;
     23     edge[tot].next = head[u];
     24     head[u] = tot++;
     25 
     26     edge[tot].to = u;
     27     edge[tot].next = head[v];
     28     head[v] = tot++;
     29 }
     30 
     31 int n;
     32 int matching[N];
     33 int check[N];
     34 bool dfs(int u){
     35     for(int i =  head[u]; i != -1; i = edge[i].next){
     36         int v = edge[i].to;
     37         if(!check[v]){//要求不在交替路
     38             check[v] = 1;//放入交替路
     39             if(matching[v] == -1 || dfs(matching[v])){
     40                 //如果是未匹配点,说明交替路为增广路,则交换路径,并返回成功
     41                 matching[u] = v;
     42                 matching[v] = u;
     43                 return true;
     44             }
     45         }
     46     }
     47     return false;//不存在增广路
     48 }
     49 
     50 //hungarian: 二分图最大匹配匈牙利算法
     51 //input: null
     52 //output: ans 最大匹配数
     53 int hungarian(){
     54     int ans = 0;
     55     memset(matching, -1, sizeof(matching));
     56     for(int u = 1; u <= n; u++){
     57         if(matching[u] == -1){
     58             memset(check, 0, sizeof(check));
     59             if(dfs(u))
     60               ans++;
     61         }
     62     }
     63     return ans;
     64 }
     65 
     66 const int MAXID = 100;
     67 int a[N], b[N], cnt;
     68 
     69 int main()
     70 {
     71     std::ios::sync_with_stdio(false);
     72     //freopen("inputE.txt", "r", stdin);
     73     while(cin>>n){
     74         init();
     75         int v;
     76         for(int i = 1; i <= n; i++){
     77             for(int j = 1; j <= n; j++){
     78                 cin>>v;
     79                 if(v){
     80                     add_edge(i, j+MAXID);
     81                 }
     82             }
     83         }
     84         int match = hungarian();
     85         if(match != n)cout<<-1<<endl;
     86         else{
     87             for(int i = 1; i <= n; i++)
     88                   matching[i]-=100;
     89             cnt = 0;
     90             for(int i = 1; i <= n; i++){
     91                 for(int j = 1; j <= n; j++){
     92                     if(i == j)continue;
     93                     if(matching[j] == i){
     94                         swap(matching[i], matching[j]);
     95                         a[cnt] = i;
     96                         b[cnt++] = j;
     97                     }
     98                 }
     99             }
    100             cout<<cnt<<endl;
    101             for(int i = 0; i < cnt; i++)
    102                   cout<<"R "<<a[i]<<" "<<b[i]<<endl;
    103         }
    104     }
    105 
    106     return 0;
    107 }
  • 相关阅读:
    OpenCV学习(7)--
    OpenCV学习(6)--更多形态转化、Hit-or-Miss变换、Hit-or-Miss变换、图像金字塔
    Linux基本操作
    设计模式
    利用Python进行数据分析:【Matplotlib】
    利用Python进行数据分析:【Pandas】(Series+DataFrame)
    利用Python进行数据分析:【NumPy】
    利用Python进行数据分析:【IPython】
    数据结构与算法(C/C++版)【排序】
    《操作系统》学习笔记
  • 原文地址:https://www.cnblogs.com/Penn000/p/7435303.html
Copyright © 2011-2022 走看看