HDU 2819 Swap
题意:
给你一个n x n的01矩阵。
可以行行交换,或者列列交换。
问:
怎样操作,可以使得矩阵的主对角线都为1.
思路:
- 先跑行列的二分图最大匹配。(可以摆棋子,且行列不冲突)
- 跑完后就存答案了
反思:
- 跑行列的二分图最大匹配。(可以摆棋子,且行列不冲突)
- 模板记得加used【j】=1;
AC
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define mp make_pair
#define mst(x,a) memset(x,a,sizeof(x))
using namespace std;
typedef pair<int,int>pa;
const int maxn=110;
int vis[maxn],n;
bool used[maxn],link[maxn][maxn];
void inita(){
mst(vis,0);
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++)scanf("%d",link[i]+j);
}
}
bool dfs(int u){
for(int j=1; j<=n; j++){
if(!used[j]&&link[u][j]){
used[j]=1;
if(!vis[j]||dfs(vis[j])){
vis[j]=u;
return 1;
}
}
}
return false;
}
void work(){
int ans=0;
for(int i=1; i<=n; i++){
mst(used,0);
ans+=dfs(i);
}
// cout<<"ok"<<endl;
if(ans<n){
printf("-1\n");
return ;
}
vector<pa>res;
for(int i=1; i<=n; i++){
int j=1;
if(vis[i]==i)continue;
for(j=1; j<=n; j++){
if(vis[j]==i)break;
}
res.push_back(mp(i,j));
swap(vis[i],vis[j]);
}
printf("%d\n",res.size());
for(int i=0; i<res.size(); i++){
printf("C %d %d\n",res[i].first,res[i].second);
}
}
int main()
{
while(~scanf("%d", &n)){
inita();
work();
}
return 0;
}