BZOJ1124: [POI2008]枪战Maf

1124: [POI2008]枪战Maf

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 501  Solved: 200
[Submit][Status][Discuss]

Description

有n个人,每个人手里有一把手枪。一开始所有人都选定一个人瞄准(有可能瞄准自己)。然后他们按某个顺序开枪,且任意时刻只有一个人开枪。因此,对于不同的开枪顺序,最后死的人也不同。

Input

输入n人数<1000000 每个人的aim

Output

你要求最后死亡数目的最小和最大可能

Sample Input

8
2 3 2 2 6 7 8 5

Sample Output

3 5

HINT

Source

题解:思路好题;

最小:对于一个入度为0的点,它所指的点一定会死,

   于是删除此点及其边,在找入度为0的点,成为子问题,

   然后只剩下环,画图发现环的答案为size/2;

最大:对于一条链或者一链+一环都之后剩下一个为死【入度为0的点】

   对于一个环也只会留下一个!

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#define N 1000010
using namespace std;
int n,i,j,ans1,ans2,len,h,bo;
int die[N],undie[N],q[N],a[N],in[N];
int read()
{
    int x=0,f=1; char ch;
    while (ch=getchar(),ch<‘0‘||ch>‘9‘) if (ch==‘-‘) f=-1;
    while (x=x*10+ch-‘0‘,ch=getchar(),ch>=‘0‘&&ch<=‘9‘);
    return x*f;
 }
int main()
{
    n=read();
    for (int i=1; i<=n; i++) a[i]=read(),in[a[i]]++;
    for (int i=1; i<=n; i++)
    {
        if (in[i]==0) ans1++,q[++ans2]=i;
    }
    for (int h=1; h<=ans2; h++)
    {
        int i=a[q[h]];
        if (die[i]) continue;
        die[i]=1; undie[a[i]]=1;
        --in[a[i]];
        if (in[a[i]]==0) q[++ans2]=a[i];
    }
    for (int i=1; i<=n; i++)
    if (in[i]&&!die[i])
    {
        len=bo=0;
        for (int j=i; !die[j]; j=a[j])
        {
            die[j]=1; ++len;
            bo|=undie[j];
        }
        if (!bo&&len>1) ++ans1;
        ans2+=len/2;
    }
    printf("%d %d\n",n-ans2,n-ans1);
    return 0;
}

时间: 2024-10-05 06:12:20

BZOJ1124: [POI2008]枪战Maf的相关文章

bzoj1124[POI2008]枪战maf tarjan+树规+贪心/线性DP

这代码快写死我了.....死人最多随便推推结论.死人最少,每个环可以单独考虑,每个环上挂着的每棵树也可以分别考虑.tarjan找出所有环,对环上每个点,求出选它和不选它时以它为根的树的最大独立集(就是最多活下来的人数),然后环上每个点选或不选对应的是一个“价值”,这个价值是那个点挂着的树里最多存活人数.先全都不选环上的点,算出选和不选时最大独立集的差值,问题变成有一个环,环上有一堆数(那些差值),选出一些不相邻的数使得和最大,然后我按着bzoj2151种树写了个贪心....这个贪心的思路也很神,

【BZOJ1124】[POI2008]枪战Maf 贪心+思路题

[BZOJ1124][POI2008]枪战Maf Description 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开枪.因此,对于不同的开枪顺序,最后死的人也不同. Input 输入n人数<1000000 每个人的aim Output 你要求最后死亡数目的最小和最大可能 Sample Input 8 2 3 2 2 6 7 8 5 Sample Output 3 5 题解:最大:首先入度为0的点一定不会死:另外,

BZOJ 1124: [POI2008]枪战Maf

1124: [POI2008]枪战Maf Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 617  Solved: 236[Submit][Status][Discuss] Description 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开枪.因此,对于不同的开枪顺序,最后死的人也不同. Input 输入n人数<1000000 每个人的aim Output 你要求最

[POI2008]枪战Maf题解

问题 C: [POI2008]枪战Maf 时间限制: 1 Sec  内存限制: 256 MB 题目描述 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开枪.因此,对于不同的开枪顺序,最后死的人也不同. 输入 输入n人数<1000000 每个人的aim 输出 你要求最后死亡数目的最小和最大可能 样例输入 8 2 3 2 2 6 7 8 5 样例输出 3 5 本次考试最后一个题,被老师评论称难炸了--然而貌似不那么难,但你

BZOJ 1124 POI2008 枪战Maf 贪心

题目大意:给定n个神枪手,每个神枪手瞄准一个人,以一定顺序开枪,问最少和最多死多少人 首先考虑最多 对于每个联通块: 如果这个连通块只有一个人,那么这个人自杀,死亡人数为1 如果这个连通块是一个环,那么可以活下来一个人,死亡人数为size?1 否则除了叶节点之外其他人都可以死,死亡人数为size?cnt叶节点 接下来考虑最少 首先叶节点一定不能死 首先把叶节点加入队列,然后每取出一个点时,击杀他瞄准的人,然后如果他瞄准的人瞄准的人此时成为了一个叶节点,那么把这个人加入队列 最后会剩下一些环,一个

BZOJ 1124[POI2008]枪战

题面: 1124: [POI2008]枪战Maf Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 659  Solved: 259[Submit][Status][Discuss] Description 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开枪.因此,对于不同的开枪顺序,最后死的人也不同. Input 输入n人数<1000000 每个人的aim Output

枪战Maf[POI2008]

题目描述 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开枪.因此,对于不同的开枪顺序,最后死的人也不同. 输入 输入n人数<1000000 每个人的aim 输出 你要求最后死亡数目的最小和最大可能 样例输入 8 2 3 2 2 6 7 8 5 样例输出 3 5 题解 这道题--说来话长了这就.考试的时候,一画样例明显是个图论题,出了环明显要缩点,缩了点明显还有一堆什么玩意,打着打着就忘了还有疯子自杀来着= =.不算自

枪战Maf (bzoj 1124)

Description 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开枪.因此,对于不同的开枪顺序,最后死的人也不同. Input 输入n人数<1000000 每个人的aim Output 你要求最后死亡数目的最小和最大可能 Sample Input 8 2 3 2 2 6 7 8 5 Sample Output 3 5 解析拓扑 设最大存活人数 mx,最少存活人数 mn 如图,入度为 0 的点[绿框]必定存活,那么

暑假集训D9总结

考试 几乎绝望的考试= =,感觉自己啥都打不出来= =,就一道DP打了个贪心,剩下两道骗分,然而竟然排到前一半= =,不可思议= = 真是令人窒息的操作啊= = T1  [bzoj1592] Making the Grade T2  [Usaco2007 Open]Fliptile 翻格子游戏 T3  [POI2008]枪战Maf 博客 github成功炸掉了,呜呜呜 然后我就搞了一晚上+半个早晨的补档= = 顺便导致了这篇D9的总结只能在D10扔出来 令人绝望啊 生活 我已经快GG了= = 退