题目: http://www.bnuoj.com/v3/contest_show.php?cid=6865#problem/H
解法: 位置和数字可以转化成二分图模型。必须是完备匹配才有解。主要是这个限制关系比较难找。 然后就是字典序最小的二分图匹配了。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 52;
int uN,vN;
int g[MAXN][MAXN];
int linker[MAXN];
bool used[MAXN];
int match[MAXN];
bool vis[MAXN];
bool dfs(int u){
for(int v=1; v<=vN; v++){
if(g[u][v] && !vis[v]&&!used[v]){
used[v] = true;
if(linker[v] == -1 || dfs(linker[v])){
linker[v] = u;
return true;
}
}
}
return false;
}
bool check(int st){
int res = 0;
memset(linker, -1, sizeof(linker));
for(int u=st; u<=uN; u++){
memset(used, false, sizeof(used));
if(!dfs(u)) return false;
}
return true;
}
int MIN[100];
int MAX[100];
int L[100], R[100];
int n;
void init(){
memset(g, 0, sizeof(g));
for(int i=1; i<=n; i++){
L[i] = MIN[i] = 1;
R[i] = MAX[i] = n;
}
}
int main(){
int a,b,c;
int m1,m2;
while(scanf("%d %d %d", &n, &m1, &m2) != EOF){
init();
uN = vN = n;
for(int i=1; i<=m1; i++){
scanf("%d %d %d", &a, &b, &c);
for(int j=a; j<=b; j++){
MIN[j] = max(MIN[j], c);
L[c] = max(L[c], a);
R[c] = min(R[c], b);
}
}
for(int i=1; i<=m2; i++){
scanf("%d %d %d", &a, &b, &c);
for(int j=a; j<=b; j++){
MAX[j] = min(MAX[j], c);
L[c] = max(L[c], a);
R[c] = min(R[c], b);
}
}
for(int i=1; i<=n; i++){
for(int j=MIN[i]; j<=MAX[i]; j++){
if(L[j] <= i && i <= R[j])
g[i][j] = 1;
}
}
if(check(1)){
memset(vis, false, sizeof(vis));
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
if(g[i][j] && !vis[j]){
vis[j] = true;
if(check(i+1)){
printf("%d%c", j, " \n"[i==n]);
break;
}
vis[j] = false;
}
}
}
}
else cout<<-1<<endl;
}
return 0;
}