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
1≤i≤m1
,
(ai,bi,ci)
means
min{p(ai),p(ai+1),…,p(bi)}=ci
;
- For
m1<i≤m1+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
1≤i≤n
which
p(i)<q(i)
and for all
1≤j<i
,
p(j)=q(j)
.
The input consists of multiple tests. For each test:
The first line contains
3
integers
n,m1,m2
(
1≤n≤50,0≤m1+m2≤50
). Each of the following
(m1+m2)
lines contains
3
integers
ai,bi,ci
(
1≤ai≤bi≤n,1≤ci≤n
).
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.
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<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<iostream>
- 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++)
- {
- int tmp=Match[i];
- G[i][tmp]=0;
- link[tmp]=-1;
- bool fg=0;
- memset(vis,0,sizeof vis);
- for(int j=1;j<tmp;j++)
- {
- if(!vis[j] && G[i][j])
- {
- vis[j]=1;
- if(link[j]==-1 || match(link[j]))
- {
- link[j]=i;
- Match[i]=j;
- fg=1;
- break;
- }
- }
- }
- if(!fg)
- {
- G[i][tmp]=1;
- link[tmp]=i;
- }
- tmp=Match[i];
- for(int j=1;j<=n;j++)
- G[j][tmp]=0;
- }
-
-
- for(int i=1;i<=n;i++)
- printf("%d%c",Match[i],i==n?'\n':' ');
- }
- else
- puts("-1");
- }
- return 0;
- }