枪战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 的点【绿框】必定存活,那么他所指的点【红圈】必定会死(早晚的事)。所以没有一个“绿框”,我们就:mx++,mn++; //这,毫无疑问

我们可以发现:

  • 如果 2 死之前射死了他指的人,那么 mn 不变
  • 如果 2 先死了,3 的入度--,他的入度变为了 0 ,进队;当然 3 也有可能入读不为 0,那么它必定会构成环或链,想要尽量活的人多,那就要这个环或链隔一个人,打一个,最多就可以存活 len/2 个人

code

#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;
const int MX=1000001;
int n,mx,mn,q[MX],aim[MX],indu[MX];
bool die[MX],undie[MX];

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i) {
        scanf("%d",&aim[i]);
        indu[aim[i]]++;
    }
    for(int i=1;i<=n;++i) if(indu[i]==0) mn++,q[++mx]=i;
    int head=1;
    while(head<=mx)
    {
        int cur=q[head];head++;
        if(die[aim[cur]]) continue;
        die[aim[cur]]=1;
        int live=aim[aim[cur]];
        indu[live]--;
        undie[live]=1;
        if(indu[live]==0) q[++mx]=live;
    }
    for(int i=1;i<=n;++i) if(indu[i] && !die[i]) {
        int len=0,flag=0;
        for(int j=i;!die[j];j=aim[j]) {
            len++;
            flag|=undie[j];
            die[j]=1;
        }
        if(!flag && len>1) mn++;
        mx+=len/2;
    }
    printf("%d %d",n-mx,n-mn);
    return 0;
} 

原文地址:https://www.cnblogs.com/qseer/p/9740930.html

时间: 2024-10-19 21:02:13

枪战Maf (bzoj 1124)的相关文章

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 你要求最

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

BZOJ1124: [POI2008]枪战Maf

1124: [POI2008]枪战Maf Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 501  Solved: 200[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 本次考试最后一个题,被老师评论称难炸了--然而貌似不那么难,但你

【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 贪心

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

枪战Maf[POI2008]

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

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

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

10.2考试总结

你没看错,国庆第二天我就来了 第一题:基本都能水到分,这道题暴力枚举+dfs即可,注意需要两遍dfs 第二题: 这题说白了考的知识点我还没学=w= 为了以后看,我就把题解复制上去吧 问题1,最少死几个人: 没有入度的点必然不死,不死的点指向的点必死.使用拓扑排序实现,若最后剩下环且环上所有点都不死,则每个环死亡人数为(L+1)/2. 问题2,最多死几个人: 没有入度的点必然不死,若存在没有叶子且长度大于1的环,则该环上有一个人不死.其余人都可以死亡. http://blog.csdn.net/p