HDU2819-Swap-二分图匹配

把矩阵上的1建成边,把边建成点

然后跑一个二分图匹配,就找到了主对角线的元素,之后排个序就可以了

  1 /*--------------------------------------------------------------------------------------*/
  2
  3 #include <algorithm>
  4 #include <iostream>
  5 #include <cstring>
  6 #include <ctype.h>
  7 #include <cstdlib>
  8 #include <cstdio>
  9 #include <vector>
 10 #include <string>
 11 #include <queue>
 12 #include <stack>
 13 #include <cmath>
 14 #include <set>
 15 #include <map>
 16
 17 //debug function for a N*M array
 18 #define debug_map(N,M,G) printf("\n");for(int i=0;i<(N);i++) 19 {for(int j=0;j<(M);j++){ 20 printf("%d",G[i][j]);}printf("\n");}
 21 //debug function for int,float,double,etc.
 22 #define debug_var(X) cout<<#X"="<<X<<endl;
 23 #define LL long long
 24 const int INF = 0x3f3f3f3f;
 25 const LL LLINF = 0x3f3f3f3f3f3f3f3f;
 26 /*--------------------------------------------------------------------------------------*/
 27 using namespace std;
 28
 29 int N,M,T;
 30 const int maxn = 210;
 31 const int maxm = 10010;
 32
 33 struct Edge{
 34     int to,next;
 35 }edge[maxm];
 36 int head[maxn],tot;
 37 void init()
 38 {
 39     tot = 0;
 40     memset(head,-1,sizeof head);
 41 }
 42 void add_edge(int u,int v)
 43 {
 44     edge[tot].to = v;edge[tot].next = head[u];
 45     head[u] = tot++;
 46 }
 47
 48 int linker[maxn];
 49 bool used[maxn];
 50 int uN;
 51
 52 bool dfs(int u)
 53 {
 54     for(int i=head[u];~i;i =edge[i].next)
 55     {
 56         int v = edge[i].to;
 57         if(!used[v])
 58         {
 59             used[v] = true;
 60             if(linker[v] == -1 || dfs(linker[v]))
 61             {
 62                 linker[v] = u;
 63                 return true;
 64             }
 65         }
 66     }
 67     return false;
 68 }
 69
 70 int hungary()
 71 {
 72     int res = 0;
 73     memset(linker,-1,sizeof linker);
 74     for(int u=1;u<=uN;u++)
 75     {
 76         memset(used,false,sizeof used);
 77         if(dfs(u)) res++;
 78     }
 79     return res/2;
 80 }
 81 vector <pair<int,int> > op;
 82 int save[maxn];
 83
 84 bool ok()
 85 {
 86     for(int i=1;i<=N;i++) if(save[i] != i) return false;
 87     return true;
 88 }
 89
 90 int main()
 91 {
 92     while(~scanf("%d",&N))
 93     {
 94         uN = 2*N;
 95         init();
 96         for(int i=1;i<=N;i++)
 97         {
 98             for(int j=1,tmp;j<=N;j++)
 99             {
100                 scanf("%d",&tmp);
101                 if(tmp == 1)
102                 {
103                     add_edge(i,j+N);
104                     add_edge(j+N,i);
105                 }
106             }
107         }
108         int match = hungary();
109         if(match < N)
110         {
111             printf("-1\n");
112         }
113         else
114         {
115             for(int u=1;u<=N;u++)
116             {
117                 int v = linker[u] - N;
118                 //printf("[%d,%d]\n",u,v);
119                 save[u] = v;
120             }
121             op.clear();
122             while(!ok())
123             {
124                 for(int i=1;i<=N;i++)
125                 {
126                     if(save[i] != i)
127                     {
128                         op.push_back(make_pair(i,save[i]));
129                         swap(save[i],save[save[i]]);
130                     }
131                 }
132             }
133             printf("%d\n",op.size());
134             for(int i=0;i<op.size();i++)
135             {
136                 printf("R %d %d\n",op[i].first,op[i].second);
137             }
138         }
139     }
140 }
时间: 2024-10-16 12:52:44

HDU2819-Swap-二分图匹配的相关文章

hdu2819二分图匹配

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? InputThere are several test cases in the input. The first line of each test case is an

E - Swap - hdu 2819(简单二分图匹配)

题意:如果可以交换行列,问主对角线能不能全为1 分析:要想主对角线全为1很明显要有N个行列不想同的点就行了,可以用二分图匹配计算出来多能有几个.如果小与N就不能.输出要是对的就行,不必和答案一样 ************************************************************************ #include<stdio.h>#include<algorithm>#include<string.h>using namesp

BZOJ 1854 游戏(二分图匹配或并查集)

此题的二分图匹配做法很容易想,就是把属性当做s集,武器当做t集,如果该武器拥有该武器则连一条边. 那么答案就是求该二分图的最大前i个匹配.将匈牙利算法改一改,当前找不到增广路就break. 但是过这个题需要常数优化,不能每次都fillchar一遍used数组.可以用队列将使用的used点加入,然后需要初始化的时候弹出即可. # include <cstdio> # include <cstring> # include <cstdlib> # include <i

Bzoj 1562: [NOI2009]变换序列 匈牙利算法,二分图匹配

题目: http://cojs.tk/cogs/problem/problem.php?pid=409 409. [NOI2009]变换序列 ★★☆   输入文件:transform.in   输出文件:transform.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 对于N个整数0, 1, ……, N-1,一个变换序列T可以将i变成Ti,其中 定义x和y之间的距离.给定每个i和Ti之间的距离D(i,Ti), 你需要求出一个满足要求的变换序列T.如果有多个满足条

hdu 5943(素数间隔+二分图匹配)

Kingdom of Obsession Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 200    Accepted Submission(s): 64 Problem Description There is a kindom of obsession, so people in this kingdom do things ver

二分图匹配(匈牙利算法) URAL 1721 Two Sides of the Same Coin

题目传送门 1 /* 2 题意:三种人,statements,testdata,anthing.要求两个人能完成s和t两个工作,且rank相差2 3 二分图匹配:此题学习建图技巧,两个集和内部一定没有边相连,rank模4小于2和大于等于2的人才能搭配,并且相差正好2, 4 两个人会的不能一样.以上条件删选出两个集合,不能按照anthing来分. 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorit

【BZOJ1562】【jzyzOJ1730】【COGS409】NOI2009变换序列 二分图匹配

[问题描述] 对于N个整数0, 1, --, N-1,一个变换序列T可以将i变成Ti,其中 定义x和y之间的距离.给定每个i和Ti之间的距离D(i,Ti), 你需要求出一个满足要求的变换序列T.如果有多个满足条件的序列,输出其中字典序最小的一个. 说明:对于两个变换序列S和T,如果存在p<N,满足对于i=0,1,--p-1,Si=Ti且Sp<Tp,我们称S比T字典序小. [输入文件] 输入文件transform.in的第一行包含一个整数N,表示序列的长度.接下来的一行包含N个整数Di,其中Di

[SCOI2010][BZOJ1854] 游戏|二分图匹配|匈牙利算法|并查集

1854: [Scoi2010]游戏 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 3018  Solved: 1099[Submit][Status][Discuss] Description lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性.并且每种装备最多只能使用一次. 游戏进行到最后,lxhgww遇到了终极boss

线段树、最短路径、最小生成树、并查集、二分图匹配、最近公共祖先--C++模板

线段树(区间修改,区间和): #include <cstdio> #include <iostream> #include <cstring> using namespace std; int c[1000000],n,m; char s; void update(int p,int l,int r,int x,int add) { int m=(l+r) / 2; if (l==r) { c[p]+=add; return; } if (x<=m) update

POJ2584 T-Shirt Gumbo 二分图匹配(网络流)

1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 const int inf=0x3f3f3f3f; 6 const int sink=30; 7 8 struct Edge 9 { 10 int to; 11 int next; 12 int capacity; 13 14 void assign(int t,int n,int c) 15 { 16 to=t; next=n; ca