题解 | #小红开宝箱#

小红开宝箱

https://ac.nowcoder.com/acm/contest/94879/E

本题大致题意是,给出打击柱子数量即打击次数,然后给出每次打击中可能的目标对象,然后确定一个合理的打击序列,这让我们想到了基于二分图匹配的匈牙利算法:确定一个元素的匹配值,如果匹配值已经有其他元素占领,那么让占领此匹配值的元素换一个匹配值,最终达到一个合理的匹配。代码如下:

#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int a[N][3];
int e[N<<1],ne[N<<1],h[N],idx,match[N<<1];
bool st[N];
void add(int a,int b)//链式前向星存图
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
bool dfs(int u)
{
    for(int i=h[u];~i;i=ne[i])//找邻接点
    {
        int j=e[i];
        if(st[j])continue;//已经被访问
        st[j]=true;
        if(!match[j]||dfs(match[j]))//未匹配或者可以让已经占领此柱子的元素换一个匹配值
        {
            match[j]=u;
            return true;
        }
    }
    return false;
}
int main()
{
    int n;
    cin>>n;
    memset(h,-1,sizeof h);
    for(int i=1;i<=n;i++)
    {
        int k;
        cin>>k;
        for(int j=1;j<=k;j++)
        {
            int w;
            cin>>w;
            add(w,i);   //柱子w可以在第i次打
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++)
    {
         memset(st,false,sizeof st);//每次都要把标记数组复原
        if(dfs(i))ans++;//记录匹配数量
    }
    if(ans!=n)//只有匹配数量为n时,才能有合理的匹配的结果
    {
        puts("kou is angry");
        return 0;
    }
    for(int i=1;i<=n;i++)cout<<match[i]<<" ";
    return 0;
}

如果不太明白此算法,可以找匈牙利算法的相关知识

全部评论
虽然但是好像确实会超时,我看b站出题人讲解视频的时候他说过数据太弱了,这题过的人不应该过百
1 回复 分享
发布于 2024-11-20 11:08 广东
这个写的是真好,比出题人讲的都好
1 回复 分享
发布于 2024-11-20 11:00 广东
怎么想到用匈牙利算法的呢?
点赞 回复 分享
发布于 2024-11-29 18:04 美国
想问一下这题用匈牙利为什么不会超时啊 清空的时间复杂度不是总共为O(n*N)的吗
点赞 回复 分享
发布于 2024-11-10 21:03 河南

相关推荐

04-18 15:58
已编辑
门头沟学院 设计
kaoyu:这一看就不是计算机的,怎么还有个排斥洗碗?
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务