题意方法和之前的3648基本一样
注意输出解的方式,分成两部分的点集,应该遍历其中一个点集,根据染色判断选择该点集的点还是另一个点集的点
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <stack> #include <queue> #define MAXN 5005 #define MAXM 50005 #define INF 1000000000 using namespace std; int start[MAXN], end[MAXN], last[MAXN]; int n, index, scc; vector<int>g[MAXN], dag[MAXN]; int dfn[MAXN], low[MAXN], instack[MAXN]; int fa[MAXN], ha[MAXN], color[MAXN], ind[MAXN]; queue<int>q; stack<int>st; void init() { index = scc = 0; memset(instack, 0, sizeof(instack)); for(int i = 0; i < MAXN; i++) g[i].clear(), dag[i].clear(); memset(dfn, 0, sizeof(dfn)); memset(color, 0, sizeof(color)); memset(ind, 0, sizeof(ind)); memset(ha, 0, sizeof(ha)); while(!q.empty()) q.pop(); while(!st.empty()) st.pop(); } bool conflict(int lx, int ly, int rx, int ry) { if(lx >= rx && lx <= ry) return true; if(ly >= rx && ly <= ry) return true; if(rx >= lx && rx <= ly) return true; if(ry >= lx && ry <= ly) return true; return false; } void build() { for(int i = 1; i <= n; i++) for(int j = i + 1; j <= n; j++) { if(conflict(start[i], start[i] + last[i] - 1, start[j], start[j] + last[j] - 1)) g[i].push_back(j + n), g[j].push_back(i + n); if(conflict(start[i], start[i] + last[i] - 1, end[j] - last[j] , end[j] - 1)) g[i].push_back(j), g[j + n].push_back(i + n); if(conflict(end[i] - last[i], end[i] - 1, start[j], start[j] + last[j] - 1)) g[i + n].push_back(j + n), g[j].push_back(i); if(conflict(end[i] - last[i], end[i] - 1, end[j] - last[j] , end[j] - 1)) g[i + n].push_back(j), g[j + n].push_back(i); } } void tarjan(int u) { dfn[u] = low[u] = ++index; int size = g[u].size(); int v; instack[u] = 1; st.push(u); for(int i = 0; i < size; i++) { v = g[u][i]; if(!dfn[v]) { tarjan(v); low[u] = min(low[u], low[v]); } else if(instack[v]) low[u] = min(low[u], dfn[v]); } if(dfn[u] == low[u]) { scc++; do { v = st.top(); st.pop(); instack[v] = 0; fa[v] = scc; }while(v != u); } } void buildDag() { for(int u = 1; u <= 2 * n; u++) { int size = g[u].size(); for(int i = 0; i < size; i++) { int v = g[u][i]; if(fa[u] != fa[v]) dag[fa[v]].push_back(fa[u]), ind[fa[u]]++; } } } void topsort() { for(int i = 1; i <= scc; i++) if(ind[i] == 0) q.push(i); while(!q.empty()) { int u = q.front(); q.pop(); if(!color[u]) color[u] = 1, color[ha[u]] = 2; int size = dag[u].size(); for(int i = 0; i < size; i++) { int v = dag[u][i]; ind[v]--; if(ind[v] == 0) q.push(v); } } } void solve() { for(int i = 1; i <= 2 * n; i++) if(!dfn[i]) tarjan(i); for(int i = 1; i <= n; i++) if(fa[i] == fa[i + n]) { puts("NO"); return; } else ha[fa[i]] = fa[i + n], ha[fa[i + n]] = fa[i]; buildDag(); topsort(); printf("YES\n"); for(int i = 1; i <= n; i++) if(color[fa[i]] == 1) { int h1, h2, m1, m2; h1 = start[i] / 60; h2 = (start[i] + last[i]) / 60; m1 = start[i] % 60; m2 = (start[i] + last[i]) % 60; printf("%02d:%02d %02d:%02d\n", h1, m1, h2, m2); } else { int h1, h2, m1, m2; h1 = (end[i] - last[i]) / 60; h2 = end[i] / 60; m1 = (end[i] - last[i]) % 60; m2 = end[i] % 60; printf("%02d:%02d %02d:%02d\n", h1, m1, h2, m2); } } int main() { int hour, miniute; while(scanf("%d", &n) != EOF) { init(); for(int i = 1; i <= n; i++) { scanf("%d:%d", &hour, &miniute); start[i] = hour * 60 + miniute; scanf("%d:%d", &hour, &miniute); end[i] = hour * 60 + miniute; scanf("%d", &last[i]); } build(); solve(); } return 0; }