HNOI2010 plan determined

Feeling \ (2-SAT \) title with network flow a little bit like, are considering how to build map, then run the board

The \ (2-SAT \) a construction diagram thinking subject is transformed into a true a false format, then it is better to

Description

And to a map on a Hamilton circuit diagram, it is determined that it is not possible to convert a plan

\(n \leq 200\),\(m \leq 10000\)

Multiple sets of data ( \ (DOC \) I did not measure more than empty, \ (WA \) several hair)

Solution

First, a practical \ (Trick \) : plan view, \ (m \-Leq. 6 with 3N \)

The proof plan to learn when to say it

Hamilton put a loop thought of as a circle (polygon) on the plane

The point is not the way back chord on the circle (polygon diagonal), or even in outer ring

Two chords intersect conditions have to meet

for (int i = 1; i < m; ++i) {
        for (int j = i + 1; j <= m; ++j) {
            int p = id[ex[i]], q = id[ey[i]], r = id[ex[j]], s = id[ey[j]];
            if (p > q)
                swap(p, q);
            if (r > s)
                swap(r, s);
            if ((p < r && q > r && q < s || (r < p && s > p && s < q)))
                add(i, j + m), add(i + m, j), add(j, i + m), add(j + m, i);
        }
    }

Anyway, bloggers is to understand the (drawing can be emotional understanding)

Then run \ (tarjan \) is gone

Code

#include <bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm {
inline int read() {
    int res = 0, f = 1;
    char k;
    while (!isdigit(k = getchar()))
        if (k == '-')
            f = -1;
    while (isdigit(k)) res = res * 10 + k - '0', k = getchar();
    return res * f;
}
const int N = 1e4 + 10;
int dfn[N], low[N], scc[N], st[N], tot, tim, top, u[N], v[N], c[N], ex[N], ey[N], now;
vector<int> g[N];
int n, id[N], m;
bool f[300][300], vis[N];
inline void add(int u, int v) { return g[u].push_back(v), void(); }
inline void tarjan(int x) {
    dfn[x] = low[x] = ++tim;
    vis[x] = 1;
    st[++top] = x;
    int sz = g[x].size();
    for (int i = 0; i < sz; ++i) {
        int t = g[x][i];
        if (!dfn[t])
            tarjan(t), low[x] = min(low[x], low[t]);
        else if (vis[t])
            low[x] = min(low[x], dfn[t]);
    }
    if (dfn[x] == low[x]) {
        ++tot;
        while (st[top] != x) scc[st[top]] = tot, vis[st[top--]] = 0;
        scc[st[top]] = tot, vis[st[top--]] = 0;
    }
    return;
}
#define cl(x) memset(x, 0, sizeof(x))
inline void prework() {
    cl(dfn);
    cl(scc);
    cl(st);
    cl(u);
    cl(v);
    cl(ex);
    now = 0;
    tim = 0;
    tot = 0;
    top = 0;
    cl(ey);
    cl(id);
    cl(vis);
    cl(f);
    for (int i = 1; i < N; ++i) g[i].clear();
    return;
}
inline void work() {
    n = read();
    m = read();
    for (int i = 1; i <= m; ++i) {
        u[i] = read();
        v[i] = read();
        if (u[i] > v[i])
            swap(u[i], v[i]);
    }
    for (int i = 1, x, y; i <= n; ++i) {
        c[i] = read();
        id[c[i]] = i;
        if (i > 1) {
            x = c[i];
            y = c[i - 1];
            f[min(x, y)][max(x, y)] = 1;
        }
    }
    if (m > 3 * n - 6)
        return puts("NO"), void();
    f[min(c[1], c[n])][max(c[1], c[n])] = 1;
    for (int i = 1; i <= m; ++i) {
        if (f[u[i]][v[i]])
            continue;
        ex[++now] = u[i], ey[now] = v[i];
    }
    //把非回路上的点找出来
    m = now;
    for (int i = 1; i < m; ++i) {
        for (int j = i + 1; j <= m; ++j) {
            int p = id[ex[i]], q = id[ey[i]], r = id[ex[j]], s = id[ey[j]];
            if (p > q)
                swap(p, q);
            if (r > s)
                swap(r, s);
            if ((p < r && q > r && q < s || (r < p && s > p && s < q)))
                add(i, j + m), add(i + m, j), add(j, i + m), add(j + m, i);
        }
    }
    for (int i = 1; i <= m * 2; ++i)
        if (!dfn[i])
            tarjan(i);
    for (int i = 1; i <= m; ++i)
        if (scc[i] == scc[i + m])
            return puts("NO"), void();
    puts("YES");
    return;
}
signed main() {
    int T = read();
    while (T--) prework(), work();
    return 0;
}
}  // namespace yspm
signed main() { return yspm::main(); }

Guess you like

Origin www.cnblogs.com/yspm/p/12324678.html