zoukankan      html  css  js  c++  java
  • POJ 3683 Priest John's Busiest Day

    POJ_3683

    这是一个2-SAT的问题,其实算法以及构图并不难想,但是编码的复杂度比较高。

    在构图的时候,我们需要判断两段时间是否相交,比较容易的办法就是if(s1<t2&&t1>s2),其中[s1,t1][s2,t2]为两段时间。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #define MAXD 2010
    #define MAXM 4000010
    int S[MAXD], T[MAXD], D[MAXD], N;
    int Gfirst[MAXD], Gnext[MAXM], Gv[MAXM], Ge;
    int gfirst[MAXD], gnext[MAXM], gv[MAXM], ge, dg[MAXD][MAXD], del[MAXD];
    int dfn[MAXD], color[MAXD], low[MAXD], cnt, col;
    int ins[MAXD], s[MAXD], top, group[MAXD][MAXD], num[MAXD];
    int topo[MAXD], vis[MAXD], t, ans[MAXD], res;
    int cmp(const void * _p,const void * _q)
    {
    int *p = (int *)_p;
    int *q = (int *)_q;
    return *p - *q;
    }
    void add_G(int i, int j)
    {
    Gv[Ge] = j;
    Gnext[Ge] = Gfirst[i];
    Gfirst[i] = Ge;
    Ge ++;
    }
    void add_g(int i, int j)
    {
    gv[ge] = j;
    gnext[ge] = gfirst[i];
    gfirst[i] = ge;
    ge ++;
    }
    void init()
    {
    int i, j, a, b;
    char str[10];
    for(i = 0; i < N; i ++)
    {
    scanf("%s", str);
    sscanf(str, "%d:%d", &a, &b);
    S[i] = a * 60 + b;
    scanf("%s", str);
    sscanf(str, "%d:%d", &a, &b);
    T[i] = a * 60 + b;
    scanf("%d", &D[i]);
    }
    Ge = 0;
    memset(Gfirst, -1, sizeof(Gfirst));
    for(i = 0; i < N; i ++)
    {
    int si0 = S[i], si1 = T[i] - D[i], ti0 = S[i] + D[i], ti1 = T[i];
    for(j = i + 1; j < N; j ++)
    {
    int sj0 = S[j], sj1 = T[j] - D[j], tj0 = S[j] + D[j], tj1 = T[j];
    if(si0 < tj0 && ti0 > sj0)
    {
    add_G(2 * i, 2 * j + 1);
    add_G(2 * j, 2 * i + 1);
    }
    if(si0 < tj1 && ti0 > sj1)
    {
    add_G(2 * i, 2 * j);
    add_G(2 * j + 1, 2 * i + 1);
    }
    if(si1 < tj0 && ti1 > sj0)
    {
    add_G(2 * i + 1, 2 * j + 1);
    add_G(2 * j, 2 * i);
    }
    if(si1 < tj1 && ti1 > sj1)
    {
    add_G(2 * i + 1, 2 * j);
    add_G(2 * j + 1, 2 * i);
    }
    }
    }
    }
    void tarjan(int u)
    {
    int i, e;
    dfn[u] = low[u] = ++ cnt;
    for(e = Gfirst[u]; e != -1; e = Gnext[e])
    {
    if(!dfn[Gv[e]])
    {
    s[top ++] = Gv[e];
    ins[Gv[e]] = 1;
    tarjan(Gv[e]);
    if(low[Gv[e]] < low[u])
    low[u] = low[Gv[e]];
    }
    else if(ins[Gv[e]] && dfn[Gv[e]] < low[u])
    low[u] = dfn[Gv[e]];
    }
    if(low[u] == dfn[u])
    {
    for(i = 0, s[top] = -1; s[top] != u; i ++)
    {
    top --;
    ins[s[top]] = 0;
    color[s[top]] = col;
    group[col][i] = s[top];
    }
    num[col] = i;
    col ++;
    }
    }
    void dfs(int u)
    {
    int e;
    vis[u] = 1;
    for(e = gfirst[u]; e != -1; e = gnext[e])
    if(!vis[gv[e]])
    dfs(gv[e]);
    topo[-- t] = u;
    }
    void toposort()
    {
    int i;
    t = col;
    memset(vis , 0, sizeof(vis));
    for(i = 0; i < col; i ++)
    if(!vis[i])
    dfs(i);
    }
    void del_g(int u)
    {
    int e;
    del[u] = 1;
    for(e = gfirst[u]; e != -1; e = gnext[e])
    if(!del[gv[e]])
    del_g(gv[e]);
    }
    int com()
    {
    int i, j, e;
    cnt = top = col = 0;
    memset(dfn, 0, sizeof(dfn));
    memset(ins, 0, sizeof(ins));
    for(i = 0; i < 2 * N; i ++)
    if(!dfn[i])
    {
    s[top ++] = i;
    ins[i] = 1;
    tarjan(i);
    }
    for(i = 0; i < 2 * N; i ++)
    {
    if(color[i] == color[i ^ 1])
    return 0;
    }
    ge = 0;
    memset(gfirst, -1, sizeof(gfirst));
    memset(dg, 0, sizeof(dg));
    for(i = 0; i < 2 * N; i ++)
    for(e = Gfirst[i]; e != -1; e = Gnext[e])
    if(color[i] != color[Gv[e]] && !dg[color[Gv[e]]][color[i]])
    {
    dg[color[Gv[e]]][color[i]] = 1;
    add_g(color[Gv[e]], color[i]);
    }
    toposort();
    memset(del, 0, sizeof(del));
    res = 0;
    for(i = 0; i < col; i ++)
    if(!del[topo[i]])
    {
    del[topo[i]] = 1;
    for(j = 0; j < num[topo[i]]; j ++)
    {
    int p = group[topo[i]][j];
    ans[res ++] = p;
    if(!del[color[p ^ 1]])
    del_g(color[p ^ 1]);
    }
    }
    return 1;
    }
    void printpath()
    {
    int i;
    qsort(ans, res, sizeof(ans[0]), cmp);
    for(i = 0; i < res; i ++)
    {
    int p = ans[i] / 2;
    if(ans[i]%2 == 0)
    {
    printf("%02d:%02d ", S[p] / 60, S[p] % 60);
    printf("%02d:%02d\n", (S[p] + D[p]) / 60, (S[p] + D[p]) % 60);
    }
    else
    {
    printf("%02d:%02d ", (T[p] - D[p]) / 60, (T[p] - D[p]) % 60);
    printf("%02d:%02d\n", T[p] / 60, T[p] % 60);
    }
    }
    }
    int main()
    {
    while(scanf("%d", &N) == 1)
    {
    init();
    if(com())
    {
    printf("YES\n");
    printpath();
    }
    else
    printf("NO\n");
    }
    return 0;
    }


  • 相关阅读:
    JSCover(查看代码覆盖率)
    vue的测试(Vue.js devtool)
    QUnit使用
    实现网站国际化
    hexo部署Github博客
    grunt实现修改代码实时刷新浏览器
    this指向问题
    gulp使用 实现文件修改实时刷新
    数据类型的判断
    template
  • 原文地址:https://www.cnblogs.com/staginner/p/2198758.html
Copyright © 2011-2022 走看看