Description
You're given a matrix with n rows and n columns. A basic property of a square matrix is the main diagonal: all cells that have the same row and column number.
We consider all diagonals that are parallel to the main one. We consider them from left-low corner to the right-upper one. So, the first cell of each diagonal will be, in order: (n, 1) (n - 1, 1) ... (1, 1) (1, 2) ... (1, n).
You need to choose one number from each diagonal. More, all 2*n-1 numbers must be pairwise distinct.
Input
The first line contains number n (1 ≤ n ≤ 300). Next n lines contain n numbers, representing the elements of the matrix. All elements of the matrix are between 1 and 109.
Output
If there is no solution, output "NO". Otherwise, output "YES". Next, on the same line, output 2n-1 numbers, separated by spaces. Each number represents the chosen value from a diagonal. Diagonals are considered in the order given by the problem.
Sample Input
21 11 1
NO
<span style="font-size:18px;">#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#define INF 0xffff777
#define N 100000
using namespace std;
int p, n;//p,n配对
int match[N];//存储每个点的匹配点
bool vis[N];
int fa[N];
int tep[100000];
vector<int> e[N];//邻接表
void InitRead();
void DataProcess();
bool Dfs(int x);
int main()
{
int t=1;
while (t--)
{
InitRead();
DataProcess();
}
return 0;
}
void InitRead()
{
int num[303][303];
scanf("%d", &n);//输入p,n的数量
memset(match, -1, sizeof(match));
memset(fa, -1, sizeof(fa));
memset(tep, 0, sizeof(tep));
map<int,int > mp;
int cnt=1;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j){
scanf("%d",&num[i][j]);
tep[cnt++]=num[i][j];
}
unique(tep+1,tep+cnt);
for(int i=1;i<=cnt-1;++i){
if(!mp.count(tep[i])){
mp[tep[i]]=i;
}
}
int a, b;
int ln=n;
n=2*n-1,p=n*n;
//printf(" n%d\n",n);
for (int i=1; i<=n; ++i)
{
e[i].clear();
//printf(" i %d\n",i);
if(i<=ln)
for(int j=1,k=ln-i+1;j<=ln&&k<=ln;++j,++k){
e[i].push_back(mp[num[j][k]]);
//printf("a %d\n",i);
}
else if(i>ln){
int tmp=i-ln;
for(int j=tmp+1,k=1;j<=ln&&k<=ln;++j,++k){
e[i].push_back(mp[num[j][k]]);
}
}
//printf("%d %d\n",i,e[i].size());
/*scanf("%d", &a);
while (a--)
{
scanf("%d", &b);
e[i].push_back(b);//p与b相连
}*/
}
return;
}
void DataProcess()
{
int ans = 0;
for (int i=1; i<=n; ++i)
{
memset(vis, false, sizeof(vis));
if (Dfs(i)) ans++; //寻找配对,成功的话ans++
//printf(" %d %d %d\n",i,e[i].size(),ans);
}
printf("%s ", ans == n ? "YES" : "NO");
if(ans ==n)
for(int i=n;i>=1;--i)
printf("%d ",tep[fa[i]]);
return;
}
bool Dfs(int x)
{
int size = e[x].size();
for (int i=0; i<size; ++i)
{
if (!vis[e[x][i]])
{
vis[e[x][i]] = true;
if (match[e[x][i]] == -1 || Dfs(match[e[x][i]]))//如果可以找到增广路
{
match[e[x][i]] = x;
fa[x]=e[x][i];
return true;
}
}
}
return false;
}</span>