Jzoj3163 排列

给你M个对1到N的排列的特征,特征有两种:

1 x y v:排列的第x个数到第y个数之间的最大值为v

2 x y v:排列的第x个数到第y个数之间的最小值为v

要求你还原出这个排列(N<=200,M<=40000)

刷水题有利于身心健康

但你还不是不会做?额这

想必许多人看完题目就知道怎么做了吧,才200直接二分图匹配就搞定了啊,O(NM)建图没问题

(另外,2014年那时候还没有匈牙利算法吗?为什么好多人直接写暴力网络流还跑的飞快)

#pragma GCC opitmize("O3")
#pragma G++ opitmize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
char s[210][210];
int n,m,f[210],v[210];
inline bool match(int x){
	for(int j=1;j<=n;++j)
		if(s[x][j]&&!v[j]){
			v[j]=1;
			if(!f[j]||match(f[j])){
				f[j]=x; return 1;
			}
		}
	return 0;
}
int main(){
	scanf("%d%d",&n,&m);
	memset(s,1,sizeof s);
	for(int o,l,r,v;m--;){
		scanf("%d%d%d%d",&o,&l,&r,&v);
		if(o==1) 
			for(int i=l;i<=r;++i) memset(s[i]+v+1,0,n-v);
		else for(int i=l;i<=r;++i) memset(s[i],0,v);
		for(int i=1;i<l;++i) s[i][v]=0;rt
		for(int i=n;i>r;--i) s[i][v]=0;
	}
	for(int i=1;i<=n;++i){
		memset(v,0,sizeof v);
		if(!match(i)) return 0&puts("-1"); 
	}
	for(int i=1;i<=n;++i) v[f[i]]=i;
	for(int i=1;i<=n;++i) printf("%d ",v[i]);
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值