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.
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).
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
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