您的位置:首页 > 其它

hdu2819 Swap

2011-07-15 16:28 148 查看
就是简单的二分匹配,行和列匹配就可以了,关键是点不在于匹配而在于排序,因为匹配后的match存储的是列的匹配对象,所以只需要把列从小到大(或者从大到小,因为是special judge,所以主副对角线都是一样)排序,每排序一次就保存当前交换了的下标,注意这里不能用冒泡而最好用选择,因为题目要求len不能大于1000,,这里纠结了一下,郁闷死了)

# include <iostream>
using namespace std;
const int size = 110;
int mapp[size][size];
int match[size];
int flag[size];
int n;
int dfs(int x)
{
for (int i = 1; i <= n; i ++){
if (!mapp[x][i] || flag[i])continue;
flag[i] = 1;
if (!match[i] || dfs(match[i])){
match[i] = x;
return 1;
}
}
return 0;
}
int main()
{
while (scanf("%d", &n) != EOF){
for (int i = 1; i <= n; i ++){
for (int j = 1; j <= n; j ++){
scanf("%d", &mapp[j][i]);
}
}
int counter = 0;
bool jud = false;
memset(match, 0, sizeof(match));
for (int i = 1; i <= n; i ++){
memset(flag, 0, sizeof(flag));
if (dfs(i)){
counter ++;
}
else jud=true;
}
if (jud){printf("-1\n");continue;}
int ans1[size], ans2[size];
int len = 0;
for (int i = 1; i <= n; i ++){
int x = i;
for (int j = i; j <= n; j ++){
if (match[x]>match[j]){
x= j;
}
}
if (x != i){
ans1[len] = i, ans2[len ++]=x;
swap(match[i], match[x]);
}
}
printf("%d\n", len);
for (int i =0 ; i < len ; i ++){
printf("R %d %d\n", ans1[i], ans2[i]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: