[SCU4443] Range Query [2015 Sichuan Province Contest Final H]

来源:互联网 发布:网络诈骗支付宝转账 编辑:程序博客网 时间:2024/05/22 08:03

题意

求一个排列,使得限制成立。限制形如[l,r]之间最大值或最小值是几

题解

按照字典序枚举每一位,枚举到某一位时用最大匹配判定此时是否有解,有解则可以进行下一位的确定

代码

/****************************************\* Author : ztx* Title  : H - Range Query* ALG    : 完备匹配+最小字典序* CMT    : 最大匹配判定+从小到大枚举* Time   :\****************************************/#include <cstdio>#define Rep(i,l,r) for(i=(l);i<=(r);i++)#define rep(i,l,r) for(i=(l);i< (r);i++)#define Rev(i,r,l) for(i=(r);i>=(l);i--)#define rev(i,r,l) for(i=(r);i> (l);i--)typedef long long ll ;typedef double lf ;int CH , NEG ;template <typename TP>inline void read(TP& ret) {    ret = NEG = 0 ; while (CH=getchar() , CH<'!') ;    if (CH == '-') NEG = true , CH = getchar() ;    while (ret = ret*10+CH-'0' , CH=getchar() , CH>'!') ;    if (NEG) ret = -ret ;}template <typename TP>inline void readc(TP& ret) {    while (ret=getchar() , ret<'!') ;    while (CH=getchar() , CH>'!') ;}template <typename TP>inline void reads(TP *ret) {    ret[0]=0;while (CH=getchar() , CH<'!') ;    while (ret[++ret[0]]=CH,CH=getchar(),CH>'!') ;    ret[ret[0]+1]=0;}#include <cstring>#define  maxn  55LLint n , m1 , m2 ;int matched[maxn] , yx[maxn] ;bool g[maxn][maxn] , vis[maxn] ;bool augment(int u) {    for (int v = 1; v <= n; v ++ )        if (g[u][v] && !matched[v] && !vis[v])            if (vis[v] = true, !yx[v] || augment(yx[v]))                return yx[v] = u , true ;    return false ;}int main() {int i , j , k , a , b , c , max_match ;//  #define READ    #ifdef  READ        freopen(".in" ,"r",stdin ) ;        freopen(".out","w",stdout) ;    #endif    while (scanf("%d%d%d", &n, &m1, &m2) != EOF) {        Rep (i,1,n) Rep (j,1,n) g[i][j] = true ;        // input min        Rep (i,1,m1) {            read(a) , read(b) , read(c) ;            Rep (j,a,b) rep (k,1,c) g[j][k] = false ;            rep (j,1,a) g[j][c] = false ;            rev (j,n,b) g[j][c] = false ;        }        // input max        Rep (i,1,m2) {            read(a) , read(b) , read(c) ;            Rep (j,a,b) rev (k,n,c) g[j][k] = false ;            rep (j,1,a) g[j][c] = false ;            rev (j,n,b) g[j][c] = false ;        }        // get max_match        memset(matched,0,sizeof matched) ;        memset(yx,0,sizeof yx) ;        max_match = 0 ;        Rep (i,1,n) {            memset(vis,0,sizeof vis) ;            if (augment(i)) max_match ++ ;        }        // enumerate        if (max_match == n) {            Rep (i,1,n) {// enumerate position                Rep (j,1,n) {// enumerate matching-number                    if (!g[i][j] || matched[j]) continue ;                    matched[j] = true ;                    memset(yx,0,sizeof yx) ;                    a = true ;                    Rep (k,i+1,n)                        if (memset(vis,0,sizeof vis) , !augment(k)) {                            a = false ;                            break ;                        }                    if (a) break ;                    matched[j] = false ;                }                printf("%d%c", j, i==n ? '\n':' ') ;            }        } else puts("-1") ;    }    #ifdef  READ        fclose(stdin) ; fclose(stdout) ;    #else        getchar() ; getchar() ;    #endif    return 0 ;}
0 0