Description
![Download as PDF Download as PDF](http://uva.onlinejudge.org/components/com_onlinejudge/images/button_pdf.png)
Bytetown has a long tradition in organizing an international flower exhibition. Professor Feuerbach, a true flower lover, visited the exhibition this year. He was pleased by the most beautiful flowers and other plants around the world roses, orchids, magnolias, cactuses. All flowers were nicely placed.
The flower placement that was the most appealing to him was composed of many kinds of flowers placed in a rectangular grid, such that each row of the grid contained each kind of flowers exactly once and each column of the grid contained each kind of flowers at most once.
Professor Feuerbach is a good mathematician and soon he realized that the number of columns of the grid has to be the same as the number of different kinds of flowers in the placement. The different kinds of flowers are represented by numbers 1, 2..., N, where N is the number of different kinds of flowers. Soon he encountered a new problem. He would like to add one row of flowers to the placement without violating the rules stated above. (Note that he may not modify the existing rows and therefore he may not use any new kinds of flowers in the new rows.) It's quite easy, but he wants to know the K-th lexicographically valid placement.
Input
The input data set describes about 100 flower placements. In the first line the number of placements is given.
Each flower placement description begins with three positive integers N (1N
200), M (0
M
N), K (1
K
200) representing the number of columns and rows of the grid. The following M lines contain N integers each representing the kinds of flowers in one row of the placement.
Output
For each flower placement output one line containing N numbers, describing the added row. The numbers in the output file should be separated by exactly one space. If there are less than K valid placements, output `-1' instead.
Sample Input
2 3 2 2 3 2 1 1 3 2 4 2 2 1 4 3 2 2 1 4 3
Sample Output
Case #1: -1 Case #2: 4 3 2 1
题意:有N个格子,每个格子要填一个数字,使得格子之间两两不一样,并且每个格子的有些数字是不能填的,问字典序第K小的方案是什么。
思路:首先我们用匈牙利跑一个完美匹配出来,如果不存在,表示无解。如果存在,我们在这个匹配的基础上进行调整,从字典序第一小搜到第K小,再将其输出就行了。每个位置从小到大的枚举匹配的数字,然后判断把数字改成这个后,是否还存在完美匹配。可以就枚举下一个位置的数字,否则就枚举下一个数字。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <ctime>
#include <queue>
using namespace std;
#define clr(a,x) memset(a,x,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<(b);++i)
const int maxn=210+5;
vector<int> adj[maxn];
int linky[maxn];
bool vst[maxn][maxn];
int n,m,k;
void input()
{
clr(vst,0);
scanf("%d%d%d",&n,&m,&k);
rep(i,1,m+1) rep(j,1,n+1) {
int x; scanf("%d",&x);
vst[j][x]=true;
}
for(int i=0;i<maxn;++i) adj[i].clear();
rep(i,1,n+1) rep(j,1,n+1)
if(!vst[i][j]) adj[i].push_back(j);
}
bool vis[maxn];
int ans[maxn];
bool dfs(int u,int a)
{
if(vis[u]) return false;
vis[u]=true;
for(int i=0;i<adj[u].size();++i) {
int v=adj[u][i];
if(linky[v]==a||dfs(linky[v],a)) {
linky[v]=u;
ans[u]=v;
return true;
}
}
return false;
}
bool solve(int u)
{
if(u==n+1)
return (--k)<=0;
vis[u]=true;
for(int i=0;i<adj[u].size();++i) {
int v=adj[u][i];
if(v==ans[u]) {
if(solve(u+1)) return true;
continue;
}
if(dfs(linky[v],u)) {
memset(vis+u+1,0,n-u);
ans[u]=v;
linky[v]=u;
int a=ans[u],l=linky[v];
if(solve(u+1)) return true;
ans[u]=a;
linky[v]=l;
} else memset(vis+u+1,0,n-u);
}
vis[u]=false;
return false;
}
bool pre_init()
{
clr(linky,-1);
int ans=0;
for(int i=1;i<=n;++i) {
clr(vis,0);
ans+=dfs(i,-1);
}
return ans==n;
}
int main()
{
//freopen("in.txt","r",stdin);
int T;cin>>T;
for(int Cas=1;Cas<=T;++Cas) {
input();
printf("Case #%d: ",Cas);
if(!pre_init()) { puts("-1"); continue; }
clr(vis,0);
if(!solve(1)) { puts("-1"); continue; }
printf("%d",ans[1]);
for(int i=2;i<=n;++i) printf(" %d",ans[i]);
puts("");
}
}