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

58 篇文章 1 订阅
5 篇文章 0 订阅

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<i p(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


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

[cpp]  view plain  copy
  1. #include<cstdio>  
  2. #include<cstring>  
  3. #include<algorithm>  
  4. #include<iostream>  
  5. using namespace std;  
  6. const int mmax  = 60;  
  7.   
  8. int max_num[mmax],min_num[mmax];  
  9. int L[mmax],R[mmax];  
  10. bool G[mmax][mmax];  
  11. int n,m1,m2;  
  12. void init()  
  13. {  
  14.     memset(G,0,sizeof G);  
  15.     for(int i=1;i<=n;i++)  
  16.     {  
  17.         L[i]=min_num[i]=1;  
  18.         R[i]=max_num[i]=n;  
  19.     }  
  20. }  
  21. int link[mmax];  
  22. bool vis[mmax];  
  23. int Match[mmax];  
  24. bool match(int x)  
  25. {  
  26.     for(int i=1;i<=n;i++)  
  27.     {  
  28.         if(G[x][i] && !vis[i])  
  29.         {  
  30.             vis[i]=1;  
  31.             if(link[i]==-1 || match(link[i]))  
  32.             {  
  33.                 link[i]=x;  
  34.                 Match[x]=i;  
  35.                 return 1;  
  36.             }  
  37.         }  
  38.     }  
  39.     return 0;  
  40. }  
  41. int hungury()  
  42. {  
  43.     int cnt=0;  
  44.     memset(link,-1,sizeof link);  
  45.     for(int i=1;i<=n;i++)  
  46.     {  
  47.         memset(vis,0,sizeof vis);  
  48.         if(match(i))  
  49.             cnt++;  
  50.     }  
  51.     return cnt;  
  52. }  
  53. int main()  
  54. {  
  55.     int a,b,c;  
  56.     while(~scanf("%d %d %d",&n,&m1,&m2))  
  57.     {  
  58.         init();  
  59.         for(int i=1;i<=m1;i++)  
  60.         {  
  61.             scanf("%d %d %d",&a,&b,&c);  
  62.             for(int j=a;j<=b;j++)  
  63.                 min_num[j]=max(min_num[j],c);  
  64.             L[c]=max(L[c],a);  
  65.             R[c]=min(R[c],b);  
  66.         }  
  67.         for(int i=1;i<=m2;i++)  
  68.         {  
  69.             scanf("%d %d %d",&a,&b,&c);  
  70.             for(int j=a;j<=b;j++)  
  71.                 max_num[j]=min(max_num[j],c);  
  72.             L[c]=max(L[c],a);  
  73.             R[c]=min(R[c],b);  
  74.         }  
  75.   
  76.         for(int i=1;i<=n;i++)  
  77.         {  
  78.             for(int j=min_num[i];j<=max_num[i];j++)  
  79.             {  
  80.                 if(L[j]<=i && i<=R[j])  
  81.                     G[i][j]=1;  
  82.             }  
  83.         }  
  84.         int num = hungury();  
  85.         if(num==n)  
  86.         {  
  87.   
  88. //            for(int i=1;i<=n;i++)  
  89. //                printf("%d%c",Match[i],i==n?'\n':' ');  
  90.   
  91.             for(int i=1;i<=n;i++)  
  92.             {  
  93.                 int tmp=Match[i];  
  94.                 G[i][tmp]=0;  
  95.                 link[tmp]=-1;  
  96.                 bool fg=0;  
  97.                 memset(vis,0,sizeof vis);  
  98.                 for(int j=1;j<tmp;j++)  
  99.                 {  
  100.                     if(!vis[j] && G[i][j])  
  101.                     {  
  102.                         vis[j]=1;  
  103.                         if(link[j]==-1 || match(link[j]))  
  104.                         {  
  105.                             link[j]=i;  
  106.                             Match[i]=j;  
  107.                             fg=1;  
  108.                             break;  
  109.                         }  
  110.                     }  
  111.                 }  
  112.                 if(!fg)  
  113.                 {  
  114.                     G[i][tmp]=1;  
  115.                     link[tmp]=i;  
  116.                 }  
  117.                 tmp=Match[i];  
  118.                 for(int j=1;j<=n;j++)  
  119.                     G[j][tmp]=0;  
  120.             }  
  121.   
  122.   
  123.             for(int i=1;i<=n;i++)  
  124.                 printf("%d%c",Match[i],i==n?'\n':' ');  
  125.         }  
  126.         else  
  127.             puts("-1");  
  128.     }  
  129.     return 0;  
  130. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值