题意大概是,一个矩阵,问你能不能通过换行或者换列的方法,使其主对角线上都为1。
脑洞:其实想到了,就又是一道模板题。
我们列号作为X集合中的每一个点,再将每一列中所出现的1的行数作为Y集合中的点,所以读进来的图就可以直接作为我们的边图,然后就是匹配了。
int m[len][len];
int l[len], x[len], y[len];
int vis[len];
int n;
int main(){
while (cin >> n) {
Init();
for (int i=1; i<=n; i++){
for (int j=1; j<=n; j++){
cin >> m[i][j];
}
}
int ans = 0, num = 0;
for (int i=1; i<=n; i++){
memset(vis, 0, sizeof(vis));
if (find(i)) ans++;
}
if (ans != n) {
cout << "-1" << endl;
continue;
}
//如果列号和行数不相等,那就说明没有归位,那就和她行号相同的一个,然后归位
for (int i=1; i<=n; i++){
if (l[i] != i){
for (int j=1; j<=n; j++){
if (i == l[j])
{
x[num] = i;
y[num] = j;
num++;
swap(l[i], l[j]);
break;
}
}
}
}
cout << num << endl;
for (int i=0; i<num; i++)
cout << "C "<< x[i] << " " << y[i] << endl;
}
return 0;
}
bool find(int p){
for (int i=1; i<=n; i++){
if (vis[i] == 0 && m[p][i] != 0){
vis[i] ++;
if (l[i] == 0 || find(l[i])){
l[i] = p;
return true;
}
}
}
return false;
}
void Init(){
memset(m, 0, sizeof(m));
memset(l, 0, sizeof(l));
memset(x, 0, sizeof(x));
memset(y, 0, sizeof(y));
memset(vis, 0, sizeof(vis));
}