POJ 3683 2-SAT

題名

ポータルPOJ3683司祭ジョンの最も忙しい日

回答

ブール変数xix_iを定義しますバツ xiistrue⇔式典iは結婚式の初めに行われますx_istrue \ Leftrightarrow式典iは結婚式の初めに行われます バツ本当ですか器具の式I結婚式式の開口を開始するときに保持された O(N 2)O(NO N2結婚式の開始時と終了時に式典を開催できる期間を列挙し、異なる結婚式の対立に属する2つの式典のパラダイムを作成して取得し、対応するマップを作成します。タルジャンタルジャンT A R&LT J A N-アルゴリズム2 - SAT 2-SAT2S A Tの問題。合計時間計算量O(N 2)O(N ^ 2)O N2

#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 2 * 1005, maxm = maxn * maxn;
int N, S[maxn], T[maxn], D[maxn];
int tot, head[maxn], to[maxm], nxt[maxm];
int num, scc, sc[maxn], dfn[maxn], low[maxn];
int top, st[maxn];
bool ins[maxn];

inline void add(int x, int y) {
    
     to[++tot] = y, nxt[tot] = head[x], head[x] = tot; }

void tarjan(int x)
{
    
    
    low[x] = dfn[x] = ++num;
    st[++top] = x, ins[x] = 1;
    for (int i = head[x]; i; i = nxt[i])
    {
    
    
        int y = to[i];
        if (!dfn[y])
            tarjan(y), low[x] = min(low[x], low[y]);
        else if (ins[y])
            low[x] = min(low[x], dfn[y]);
    }
    if (low[x] == dfn[x])
    {
    
    
        ++scc;
        int y;
        do
        {
    
    
            y = st[top--], ins[y] = 0, sc[y] = scc;
        } while (y != x);
    }
}

int main()
{
    
    
    scanf("%d", &N);
    for (int i = 1, h, m; i <= N; ++i)
    {
    
    
        scanf("%d:%d", &h, &m), S[i] = h * 60 + m;
        scanf("%d:%d", &h, &m), T[i] = h * 60 + m;
        scanf("%d", D + i);
    }
    for (int i = 1; i <= N; ++i)
        for (int j = i + 1; j <= N; ++j)
        {
    
    
            if (max(S[i], S[j]) < min(S[i] + D[i], S[j] + D[j]))
                add(i, j + N), add(j, i + N);
            if (max(S[i], T[j] - D[j]) < min(S[i] + D[i], T[j]))
                add(i, j), add(j + N, i + N);
            if (max(T[i] - D[i], S[j]) < min(T[i], S[j] + D[j]))
                add(i + N, j + N), add(j, i);
            if (max(T[i] - D[i], T[j] - D[j]) < min(T[i], T[j]))
                add(i + N, j), add(j + N, i);
        }
    int lim = N << 1;
    for (int i = 1; i <= lim; ++i)
        if (!dfn[i])
            tarjan(i);
    for (int i = 1; i <= N; ++i)
        if (sc[i] == sc[i + N])
        {
    
    
            puts("NO");
            return 0;
        }
    puts("YES");
    for (int i = 1, x, y; i <= N; ++i)
    {
    
    
        if (sc[i] < sc[i + N])
            x = S[i], y = S[i] + D[i];
        else
            x = T[i] - D[i], y = T[i];
        printf("%02d:%02d %02d:%02d\n", x / 60, x % 60, y / 60, y % 60);
    }
    return 0;
}

おすすめ

転載: blog.csdn.net/neweryyy/article/details/115037406