[POJ 3683] Priest John's Busiest Day

[题目链接]

           http://poj.org/problem?id=3683

[算法]

         2-SAT,  用拓扑排序输出可行解

[代码]

      

#include <algorithm>  
#include <bitset>  
#include <cctype>  
#include <cerrno>  
#include <clocale>  
#include <cmath>  
#include <complex>  
#include <cstdio>  
#include <cstdlib>  
#include <cstring>  
#include <ctime>  
#include <deque>  
#include <exception>  
#include <fstream>  
#include <functional>  
#include <limits>  
#include <list>  
#include <map>  
#include <iomanip>  
#include <ios>  
#include <iosfwd>  
#include <iostream>  
#include <istream>  
#include <ostream>  
#include <queue>  
#include <set>  
#include <sstream>  
#include <stdexcept>  
#include <streambuf>  
#include <string>  
#include <utility>  
#include <vector>  
#include <cwchar>  
#include <cwctype>  
#include <stack>  
#include <limits.h>
using namespace std;
#define MAXN 1010
#define MAXM 1000010

struct edge
{
        int to,nxt;
} e[MAXM << 1],ec[MAXM << 1];

int i,j,n,m,SH,SM,TH,TM,timer,top,cnt,tot,ctot;
int S[MAXN],T[MAXN],D[MAXN],low[MAXN << 1],dfn[MAXN << 1],belong[MAXN << 1],
        stk[MAXN << 1],head[MAXN << 1],chead[MAXN << 1],val[MAXN << 1],opp[MAXN << 1];
bool instack[MAXN << 1];
stack<int> s;

inline void addedge(int u,int v)
{
        tot++;
        e[tot] = (edge){v,head[u]};
        head[u] = tot;
}
inline void addcedge(int u,int v)
{
        ctot++;
        ec[ctot] = (edge){v,chead[u]};
        chead[u] = ctot;
}
inline bool illegal(int a,int b,int c,int d)
{
        if (a >= c && a < d) return true;
        if (b > c && b <= d)  return true;
        if (a <= c && b >= d) return true;
        return false;
}
inline void tarjan(int u)
{
        int i,v;
        low[u] = dfn[u] = ++timer;
        instack[u] = true;
        s.push(u);
        for (i = head[u]; i; i = e[i].nxt)
        {
                v = e[i].to;
                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])
        {
                cnt++;
                do
                {
                        v = s.top(); 
                        s.pop();
                        belong[v] = cnt;
                        instack[v] = false;
                } while (v != u);
        }
}
inline void topsort()
{
        int i,u,v;
        queue< int > q;
        static int deg[MAXN << 1];
        for (i = 1; i <= cnt; i++) 
        {
                deg[i] = 0;
                val[i] = -1;
        }
        for (u = 1; u <= 2 * n; u++)
        {
                for (i = head[u]; i; i = e[i].nxt)
                {
                        v = e[i].to;
                        if (belong[u] != belong[v]) 
                        {
                                addcedge(belong[v],belong[u]);
                                deg[belong[u]]++;
                        }
                }
        }
        for (i = 1; i <= cnt; i++)
        {
                if (!deg[i])
                        q.push(i);
        }
        while (!q.empty())
        {
                u = q.front();
                q.pop();
                if (val[u] == -1) 
                {
                        val[u] = 0; 
                        val[opp[u]] = 1;
                }
                for (i = chead[u]; i; i = ec[i].nxt)
                {
                        v = ec[i].to;
                        if (--deg[v] == 0) q.push(v);
                }
        }
        for (i = 1; i <= n; i++)
        {
                if (val[belong[i]] == 0) printf("%02d:%02d %02d:%02d\n",S[i] / 60,S[i] % 60,(S[i] + D[i]) / 60,(S[i] + D[i]) % 60);
                else printf("%02d:%02d %02d:%02d\n",(T[i] - D[i]) / 60,(T[i] - D[i]) % 60,T[i] / 60,T[i] % 60);
        }
}

int main() 
{
        
        scanf("%d",&n);
        for (i = 1; i <= n; i++)
        {
                scanf("%d:%d %d:%d %d",&SH,&SM,&TH,&TM,&D[i]);
                S[i] = SH * 60 + SM;
                T[i] = TH * 60 + TM;        
        }
        for (i = 1; i <= n; i++)
        {
                for (j = i + 1; j <= n; j++)
                {
                        if (illegal(S[i],S[i] + D[i],S[j],S[j] + D[j]))
                        {
                                addedge(i,j + n);
                                addedge(j,i + n);
                        }
                        if (illegal(S[i],S[i] + D[i],T[j] - D[j],T[j]))
                        {
                                addedge(i,j);
                                addedge(j + n,i + n);
                        }
                        if (illegal(T[i] - D[i],T[i],S[j],S[j] + D[j]))
                        {
                                addedge(i + n,j + n);
                                addedge(j,i);
                        }
                        if (illegal(T[i] - D[i],T[i],T[j] - D[j],T[j]))
                        {
                                addedge(i + n,j);
                                addedge(j + n,i);
                        }
                }
        }
        for (i = 1; i <= 2 * n; i++)
        {
                if (!dfn[i])
                    tarjan(i);
        }
        for (i = 1; i <= n; i++)
        {
                if (belong[i] == belong[i + n])
                {
                        printf("NO\n");
                        return 0;
                }
                opp[belong[i]] = belong[i + n];
                opp[belong[i + n]] = belong[i]; 
        }
        printf("YES\n");
        topsort();
        
        return 0;
    
}

猜你喜欢

转载自www.cnblogs.com/evenbao/p/9403250.html