[BZOJ2438] killing game

Description

A cold-blooded killer sneaked into the Na-wiat, and pretending to be civilians. Police hope to be in N individuals inside, find out who is the killer. The police can for everyone
were to verify, verify if the object is a civilian, he would tell the police, who he knew, who is the killer, who is a civilian. If the object is to kill verifiable
hand, the killer will get rid of the police. The police now know who mastered every individual. Everyone has probably the killer, the killer can be seen as they are the probability of
rates are the same. Q: According to the best of circumstances, to ensure its own security and police know who the killer maximum probability is how much?

\ (N \ 10 ^ 5, m \ 3 \ Times 10 ^ 5 \)

Solution

Assume optimal strategy checked \ (x \) unknown identity of the person, then the probability is \ (\ frac {n - x } {n} \)

So we checked few people as possible.

First, for a strongly connected component, as long as a person can check this strongly connected component of all security check completed.

So the first rough consider every point of a complete reduction in the degree of a dag point 0 of the investigation, it will be able to find out the killer.

Then it will be this hack:

3 2
2 1
3 1

Find the best not check 2 and 3, but only check 2 or 3.

So think carefully and found that if there is at least a point to meet the strongly connected components the size of its own where is one and it even out-degree point are \ (> 1 \) , then this point is not checked, it is necessary to check the number will be 1.

Note that even if there are multiple such points, the number will only reduce the investigation was only 1, because these must be the last remaining points, but we can not determine who the killer (or check if they will pay a higher price).

Code

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <fstream>

typedef long long LL;
typedef unsigned long long uLL;

#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define MP(x, y) std::make_pair(x, y)
#define DE(x) cerr << x << endl;
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define GO cerr << "GO" << endl;

using namespace std;

inline void proc_status()
{
    ifstream t("/proc/self/status");
    cerr << string(istreambuf_iterator<char>(t), istreambuf_iterator<char>()) << endl;
}
inline int read() 
{
    register int x = 0; register int f = 1; register char c;
    while (!isdigit(c = getchar())) if (c == '-') f = -1;
    while (x = (x << 1) + (x << 3) + (c xor 48), isdigit(c = getchar()));
    return x * f;
}
template<class T> inline void write(T x) 
{
    static char stk[30]; static int top = 0;
    if (x < 0) { x = -x, putchar('-'); }
    while (stk[++top] = x % 10 xor 48, x /= 10, x);
    while (putchar(stk[top--]), top);
}
template<typename T> inline bool chkmin(T &a, T b) { return a > b ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }

const int maxN = 2e5 + 2;

int n, m;
int stk[maxN], top;
int low[maxN], dfn[maxN], dfst;
int in[maxN], size[maxN], cnt, col[maxN];
vector<int> g[maxN];

void link(int u, int v) { g[u].push_back(v); }

void tarjan(int u)
{
    int v;
    dfn[u] = low[u] = ++dfst;
    stk[++top] = u;
    for (int i = 0; i < SZ(g[u]); ++i)
    {
        v = g[u][i];
        if (!dfn[v])
            tarjan(v), chkmin(low[u], low[v]);
        else if (!col[v])
            chkmin(low[u], dfn[v]);
    }
    if (low[u] == dfn[u])
    {
        ++cnt;
        do
        {
            v = stk[top--];
            col[v] = cnt;
            size[cnt]++;
        } while (u != v);
    }
}

bool chk(int u)
{
    if (size[col[u]] != 1) return 0;
    if (in[col[u]]) return 0;
    for (int i = 0; i < SZ(g[u]); ++i)
    {
        int v = g[u][i];
        if (in[col[v]] <= 1)
            return 0;
    }
    return 1;
}

int main() 
{
#ifndef ONLINE_JUDGE
    freopen("xhc.in", "r", stdin);
    freopen("xhc.out", "w", stdout);
#endif
    n = read(), m = read();
    for (int i = 1; i <= m; ++i) { int u = read(), v = read(); link(u, v); }
    for (int i = 1; i <= n; ++i) if (!dfn[i]) tarjan(i);
    for (int i = 1; i <= n; ++i)
        for (int j = 0; j < SZ(g[i]); ++j)
            if (col[g[i][j]] != col[i])
                in[col[g[i][j]]]++;
    int ans = 0, delta = 0;
    for (int i = 1; i <= cnt; ++i) if (!in[i]) ans++;
    for (int i = 1; i <= n; ++i) if (chk(i)) delta++;
    if (delta) printf("%.6lf\n", (double)(n - ans + 1) / n);
    else printf("%.6lf\n", (double) (n - ans) / n);
    return 0;
}

Guess you like

Origin www.cnblogs.com/cnyali-Tea/p/11417538.html