<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; }