大意略。

关键在于怎样去建图,有冲突之间的点指点连边,然后通过染色的方法去找可行的一组解。

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <map>
using namespace std;

const int maxn = 2010;
const int maxm = 1010*1010*9;

struct Edge
{
    int v, w;
    int next;
}edge[maxm], edge2[maxm];

int first2[maxn];
int cnt2;
int first[maxn], stack[maxn], ins[maxn], dfn[maxn], low[maxn];
int belong[maxn];

int n, m, k;
int cnt;
int scnt, top, tot;

void init()
{
    cnt = 0;
    cnt2 = 0;
    scnt = top = tot = 0;
    memset(first, -1, sizeof(first));
    memset(first2, -1, sizeof(first2));
    memset(dfn, 0, sizeof(dfn));
    memset(ins, 0, sizeof(ins));
    memset(low, 0, sizeof(low));
}

void read_graph(int u, int v)
{
    edge[cnt].v = v;
    edge[cnt].next = first[u], first[u] = cnt++;
}

void read_graph2(int u, int v)
{
    edge2[cnt2].v = v;
    edge2[cnt2].next = first2[u], first2[u] = cnt2++;
}

void dfs(int u)
{
    int v;
    low[u] = dfn[u] = ++tot;
    stack[top++] = u;
    ins[u] = 1;
    for(int e = first[u]; e != -1; e = edge[e].next)
    {
        v = edge[e].v;
        if(!dfn[v]) { dfs(v); low[u] = min(low[u], low[v]); }
        else if(ins[v]) { low[u] = min(low[u], dfn[v]); }
    }
    if(low[u] == dfn[u])
    {
        scnt++;
        do { v = stack[--top]; belong[v] = scnt; ins[v] = 0; } while(u != v);
    }
}

void readint(int &x)
{
    char c;
    while(!isdigit(c)) c = getchar();
    
    x = 0;
    while(isdigit(c))
    {
        x = x*10 + c-'0';
        c = getchar();
    }
}

void writeint(int x)
{
    if(x > 9) writeint(x/10);
    putchar(x%10+'0');
}

void Tarjan()
{
    for(int v = 1; v <= 2*n; v++) if(!dfn[v])
        dfs(v);
}

int judge(int start1, int last1, int start2, int last2)
{
    if(start2 < start1+last1 && start1 < start2+last2) return 1;
    return 0;
}

int sta[maxn], end[maxn], la[maxn];

void read_case()
{
    init();
    for(int i = 1; i <= n; i++)
    {
        int h1, m1, h2, m2, last;
        scanf("%d:%d %d:%d %d", &h1, &m1, &h2, &m2, &last);
        sta[i] = h1*60+m1, end[i] = h2*60+m2, la[i] = last;
    }
    
    for(int i = 1; i <= n; i++)
    for(int j = 1; j <= n; j++) if(i != j)
    {
        if(judge(sta[i], la[i], sta[j], la[j])) read_graph(i, j+n);
        if(judge(sta[i], la[i], end[j]-la[j], la[j])) read_graph(i, j);
        if(judge(end[i]-la[i], la[i], sta[j], la[j])) read_graph(i+n, j+n);
        if(judge(end[i]-la[i], la[i], end[j]-la[j], la[j])) read_graph(i+n, j);
    }
}

int hash[maxn];
int color[maxn];
int ind[maxn];

void toposort()
{
    queue<int> Q;
    
    for(int i = 1; i <= scnt; i++) if(!ind[i])
        Q.push(i);
    while(!Q.empty())
    {
        int u = Q.front(); Q.pop();
        if(!color[u]) color[u] = 1, color[hash[u]] = 2;
        for(int e = first2[u]; e != -1; e = edge2[e].next)
        {
            int v = edge2[e].v;
            if(--ind[v] == 0) Q.push(v);
        }
    }
}

void build()
{
    memset(color, 0, sizeof(color));
    memset(ind, 0, sizeof(ind));
    
    for(int u = 1; u <= 2*n; u++)
    {
        for(int e = first[u]; e != -1; e = edge[e].next)
        {
            int v = edge[e].v;
            if(belong[u] != belong[v]) read_graph2(belong[v], belong[u]), ind[belong[u]]++;
        }
    }
}

int check()
{
    for(int i = 1; i <= n; i++)
    {
        if(belong[i] == belong[i+n]) return 0;
        else hash[belong[i]] = belong[i+n], hash[belong[i+n]] = belong[i];
    }
    return 1;
}

void output()
{
    printf("YES\n");
    
    int h1, m1, h2, m2;
    for(int i = 1; i <= n; i++)
    {
        if(color[belong[i]] == 1)
        {
            h1 = sta[i]/60;
            m1 = sta[i]%60;
            
            h2 = (sta[i]+la[i])/60;
            m2 = (sta[i]+la[i])%60;
            
            printf("%02d:%02d %02d:%02d\n", h1, m1, h2, m2);
        }
        else
        {
            h1 = (end[i]-la[i])/60;
            m1 = (end[i]-la[i])%60;
            
            h2 = end[i]/60;
            m2 = end[i]%60;
            
            printf("%02d:%02d %02d:%02d\n", h1, m1, h2, m2);
        }
    }
}

void solve()
{
    read_case();
    
    Tarjan();
    
    if(check())
    {
        build();
        toposort();
        output();
    }
    else printf("NO\n");
}

int main()
{
    while(~scanf("%d", &n))
    {
        solve();
    }
    return 0;
}
View Code

 

posted on 2013-08-04 15:13  Buck Meister  阅读(159)  评论(0编辑  收藏  举报