scu oj 4443 Range Query (scoure :2015年四川省acm省赛)

     

Range Query

frog has a permutation p(1),p(2),,p(n) of {1,2,,n}. She also has m1+m2 records (ai,bi,ci) of the permutation.

  • For 1im1(ai,bi,ci) means min{p(ai),p(ai+1),,p(bi)}=ci;
  • For m1<im1+m2(ai,bi,ci) means max{p(ai),p(ai+1),,p(bi)}=ci.

Find a permutation which is consistent with above records, or report the records are self-contradictory. If there are more than one valid permutations, find the lexicographically least one.

Permutation p(1),p(2),,p(n) is lexicographically smaller than q(1),q(2),,q(n) if and only if there exists 1in which p(i)<q(i) and for all 1j<ip(j)=q(j).

Input

The input consists of multiple tests. For each test:

The first line contains 3 integers n,m1,m2 (1n50,0m1+m250). Each of the following (m1+m2) lines contains 3 integers ai,bi,ci (1aibin,1cin).

Output

For each test, write n integers p(1),p(2),,p(n) which denote the lexicographically least permutation, or ``-1'' if records are self-contradictory.

Sample Input

    5 1 1
    1 5 1
    1 5 5
    3 1 1
    1 2 2
    1 2 2

Sample Output

    1 2 3 4 5
    -1


解法:完备匹配的最小字典序。  先出最大匹配,然后枚举从小到每个点枚举最优状态,删边然后继续寻找增广路。

#include
#include
#include
#include
using namespace std;
const int mmax  = 60;

int max_num[mmax],min_num[mmax];
int L[mmax],R[mmax];
bool G[mmax][mmax];
int n,m1,m2;
void init()
{
    memset(G,0,sizeof G);
    for(int i=1;i<=n;i++)
    {
        L[i]=min_num[i]=1;
        R[i]=max_num[i]=n;
    }
}
int link[mmax];
bool vis[mmax];
int Match[mmax];
bool match(int x)
{
    for(int i=1;i<=n;i++)
    {
        if(G[x][i] && !vis[i])
        {
            vis[i]=1;
            if(link[i]==-1 || match(link[i]))
            {
                link[i]=x;
                Match[x]=i;
                return 1;
            }
        }
    }
    return 0;
}
int hungury()
{
    int cnt=0;
    memset(link,-1,sizeof link);
    for(int i=1;i<=n;i++)
    {
        memset(vis,0,sizeof vis);
        if(match(i))
            cnt++;
    }
    return cnt;
}
int main()
{
    int a,b,c;
    while(~scanf("%d %d %d",&n,&m1,&m2))
    {
        init();
        for(int i=1;i<=m1;i++)
        {
            scanf("%d %d %d",&a,&b,&c);
            for(int j=a;j<=b;j++)
                min_num[j]=max(min_num[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_num[j]=min(max_num[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_num[i];j<=max_num[i];j++)
            {
                if(L[j]<=i && i<=R[j])
                    G[i][j]=1;
            }
        }
        int num = hungury();
        if(num==n)
        {

//            for(int i=1;i<=n;i++)
//                printf("%d%c",Match[i],i==n?'\n':' ');

            for(int i=1;i<=n;i++)
            {
                int tmp=Match[i];
                G[i][tmp]=0;
                link[tmp]=-1;
                bool fg=0;
                memset(vis,0,sizeof vis);
                for(int j=1;j


你可能感兴趣的:(图论)