前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【UVALive 7334】Kernel Knights

【UVALive 7334】Kernel Knights

作者头像
饶文津
发布2020-06-02 14:39:36
3300
发布2020-06-02 14:39:36
举报
文章被收录于专栏:饶文津的专栏饶文津的专栏

题意

  有两个队的骑士1到n和n+1到2n,每个骑士只能互相攻击对手队的一个骑士。kernel的意思是在这个kernel里的骑士不会互相攻击,在kernel外的骑士被kernel里的骑士攻击。

现在告诉你所有骑士攻击的骑士,求一个kernel。

分析

没人攻击的骑士一定在kernel里,把没人攻击的加入队列,然后被他攻击的骑士一定在kernel外。

kernel外的骑士的攻击无效,因为如果一个骑士如果只被外面的骑士攻击,他就是kernel里的。

于是 被 外面的骑士攻击 的骑士 的被攻击次数 -1,如果被攻击次数为0了就加入队列。

某个导致我WA的地方:被攻击次数 -1 这个操作不能重复,所以要判断当前这个“外面的骑士”是不是已经处理过。

反例: 4 5 5 8 7 3 3 4 4 正确答案:1 2 6 7 8 重复操作的错误答案:1 2 3 6 7 8

处理完后,剩下的就是一个边数为偶数的环,只要输出它的一边就好了。

这题也可以DFS。

代码

代码语言:javascript
复制
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int maxn=2e5+100;
int n,a[maxn],d[maxn],k[maxn];
queue<int> q;

int main()
{
    while(~scanf("%d",&n))
    {
        while(!q.empty()) q.pop();
        memset(d,0,sizeof(d));
        memset(k,0,sizeof(k));
        for(int i=1; i<=2*n; i++)
        {
            scanf("%d",&a[i]);
            d[a[i]]++;
        }
        for(int i=1; i<=2*n; i++)
        {
            if(d[i]==0)q.push(i);
        }
        while(!q.empty())
        {
            int p=q.front();
            q.pop();
            k[p]=1;
            if( k[ a[p] ]==-1  )continue;//没有它而让我WA的地方
            k[a[p]]=-1;
            d[a[a[p]]]--;
            if(d[a[a[p]]]==0)q.push(a[a[p]]);
        }
        for(int i=1; i<=2*n; i++)
        {
            if(i<=n&&k[i]>=0)printf("%d ",i);
            else if(k[i]==1)printf("%d ",i);
        }
        printf("\n");
    }
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-02-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 分析
  • 代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档