題名
回答
ブール変数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-SAT2−S 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;
}