<pre name="code" class="cpp">/*****************************************
Author :Crazy_AC(JamesQi)
Time :2016
File Name :
给定n行m列的花的摆放方式,要求就是每行每列不出现同色的,求第k字典序的摆放方式。
思路:从第一行开始枚举放什么花色,然后就是判断是否和题目的要求,这里的判断方式就是
二分图的dfs部分同来进行摆放关系的调整,但是不能调整当前行前面的已经确定的花色,这
样得到的字典序不是严格从1到k递增的字典序。
还有就是G中的点是有序的。
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <climits>
using namespace std;
#define MEM(x,y) memset(x, y,sizeof x)
#define pk push_back
#define lson rt << 1
#define rson rt << 1 | 1
#define bug cout << "BUG HERE\n"
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> ii;
typedef pair<ii,int> iii;
const double eps = 1e-10;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int nCase = 0;
const int maxn = 210;
vector<int> G[maxn], vec;
bool mp[maxn][maxn];
int linker[maxn];
int vis[maxn];
int used[maxn];
int n, m, k;
inline void Input() {
scanf("%d%d%d",&n,&m,&k);
int x;
memset(mp, false,sizeof mp);
for (int i = 1;i <= m;++i) {
for (int j = 1;j <= n;++j) {
scanf("%d",&x);
mp[j][x] = true;
}
}
//根据已有的花色进行建图。
for (int i = 1;i <= n;++i) {
G[i].clear();
for (int j = 1;j <= n;++j)
if (!mp[i][j]) G[i].push_back(j);
}
//show map
// for (int i = 1;i <= n;++i) {
// for (int j = 0;j < G[i].size();++j)
// printf("%4d", G[i][j]);
// puts("");
// }
// puts("***********************");
}
bool search(int u, int limit) {
if (u <= limit) return false;
for (int i = 0;i < G[u].size();++i) {
int v = G[u][i];
if (vis[v]) continue;
vis[v] = true;
if (linker[v] == -1 || search(linker[v], limit)) {
linker[v] = u;
return true;
}
}
return false;
}
inline int Hungary() {
int ret = 0;
memset(linker, -1,sizeof linker);
for (int i = 1;i <= n;++i) {
memset(vis, 0,sizeof vis);
if (search(i, 0)) ret++;
}
return ret;
}
int cnt;
int tmp[maxn];
inline bool check(int v, int u) {
if (linker[v] == u) return true;
int t = 1;
for (int i = 1;i <= n;++i) {//T-Set
vis[i] = false;
tmp[i] = linker[i];
if (linker[i] == u) t = i;
}
int nf = linker[v];//S-Set
linker[v] = u;
linker[t] = -1;
if (search(nf, u)) return true;
else {
memcpy(linker, tmp, sizeof tmp);
return false;
}
return false;
}
bool dfs(int u) {
// cout << "u = " << u << endl;
if (u == n + 1) return ++cnt == k;
for (int i = 0;i < G[u].size();++i) {
int v = G[u][i];
if (used[v]) continue;
if (check(v, u)) {
used[v] = true;
vec.push_back(v);
if (dfs(u + 1)) return true;
vec.pop_back();
used[v] = false;
}
}
return false;
}
inline void solve() {
memset(used, 0,sizeof used);
vec.clear();
cnt = 0;
int now;
if ((now = Hungary()) == n && dfs(1)) {
for (int i = 0;i < n;++i)
printf(" %d", vec[i]);
puts("");
}else puts(" -1");
// cout << now << endl;
}
int main(int argc, const char * argv[])
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int t;
scanf("%d",&t);
while(t--) {
Input();
printf("Case #%d:", ++nCase);
solve();
}
return 0;
}
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交