[BZOJ1562]NOI2009变换序列|二分图匹配

本文探讨了如何通过优化字典序和改进匹配策略来解决二分图匹配问题,避免了多次尝试和失败。重点介绍了在实际应用中如何构建有效的边表,并采用逆序匹配技巧提高解决方案的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    一开始看错题以为是个傻逼的模拟。。不过也是个二分图匹配,但是我挂了好几次。。

    可以弄出每个位置可以放的两个数,然后可以建出二分图。。不过要满足字典序最小,我一开始是边表按to从小到大放,顺序匹配,发现好像不行。。看了网上的说要倒序匹配,想一想也是,如果有解的话后匹配的点其实是优先满足的。。

#include<iostream>
#include<cstdio>
#define N 10005
using namespace std;
int n,i,j,ne=0,m1,m2,t[N],u[N],a[N][2],pre[N],to[N];
bool find(int x,int tim)
{
    for (int i=0;i<=1;i++)
        if (u[a[x][i]]>tim) 
        {
            u[a[x][i]]=tim;
            if (pre[a[x][i]]==0||find(pre[a[x][i]]-1,tim))
            {
                pre[a[x][i]]=x+1;to[x]=a[x][i];
                return true;
            }
        }
    return false;
}
int hungary(int n)
{
    for (i=n-1;i>=0;i--)
        if (!find(i,i)) return i;
    return n;
}
int main()
{
	freopen("1562.in","r",stdin);
    scanf("%d",&n);
    for (i=0;i<n;i++) u[i]=n,pre[i]=0;
    for (i=0;i<n;i++) 
    {
        scanf("%d",&t[i]);
        m1=(i+t[i])%n;m2=(i-t[i]+n)%n;
        if (m1>m2) swap(m1,m2);
        a[i][0]=m1;a[i][1]=m2;
    }
    int ans=hungary(n);
    if (ans==n)
    {
        for (i=0;i<n-1;i++) printf("%d ",to[i]);printf("%d",to[n-1]);
    }
    else printf("No Answer");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值