[COCI2012-2013] POPUST

COCI

大意:

问能否确定1-n的一个排列满足所有条件

思路:
按题意确定每一个点和每一个位置对应的范围大小,如果能够找到一个满足条件的排列,也就意味着点与位置的约束不会互相矛盾,且能够一一匹配,所以跑一个匈牙利就可以了。

(其实赛时也有想过这个,但是经验太少,还是不知道怎么建图。。。)

确定numr,numl数组,表示每一个数字能放置的最远和最近的区间

再确定qr,ql数组,表示每一个位置能放的最大的数和最小的数 

然后按关系建边即可

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=300;
ll numl[N],numr[N],ql[N],qr[N];
ll n,m;
ll op,l,r,a;
vector<ll> vt[310];
ll ans=0;
ll dfn[N];
ll ti=0;//时间戳
ll match[N];
bool dfs(ll u,ll tim)
{
	for(ll y:vt[u])
	{
		if(dfn[y]==tim) continue;
		dfn[y]=tim;
		if(!match[y]||dfs(match[y],tim))
		{
			match[y]=u;
			return 1;
		}
	}
} 
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;++i)
	{
		numl[i]=ql[i]=1;
		numr[i]=qr[i]=n;
	}
	for(int i=1;i<=m;++i)
	{
		cin>>op>>l>>r>>a;
		numl[a]=max(numl[a],l);
		numr[a]=min(numr[a],r);
		for(int j=l;j<=r;++j)
		{
			if(op==1) qr[j]=min(qr[j],a);
			else ql[j]=max(ql[j],a);
		}
	}
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=n;++j)
		{
			if(numl[i]<=j&&numr[i]>=j&&ql[j]<=i&&qr[j]>=i) vt[i].push_back(j);
		}
	}
	for(int i=1;i<=n;++i)
	{
		if(dfs(i,++ti)) ans++;
	}
	if(ans!=n)
	{
		cout<<-1<<endl;
		return 0;
	}
	for(int i=1;i<=n;++i) cout<<match[i]<<" ";
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值