• Priest John's Busiest Day poj 3683 tarjan+2-SAT


    题意/Description:

      John is the only priest in his town. September 1st is the John's busiest day in a year because there is an old legend in the town that the couple who get married on that day will be forever blessed by the God of Love. This year N couples plan to get married on the blessed day. The i-th couple plan to hold their wedding from time Sito time Ti. According to the traditions in the town, there must be a special ceremony on which the couple stand before the priest and accept blessings. The i-th couple need Di minutes to finish this ceremony. Moreover, this ceremony must be either at the beginning or the ending of the wedding (i.e. it must be either from Si to Si +Di, or from Ti - Di to Ti). Could you tell John how to arrange his schedule so that he can present at every special ceremonies of the weddings.

      Note that John can not be present at two weddings simultaneously.

     

    读入/Input

      The first line contains a integer N ( 1 ≤ N ≤ 1000). 
      The next N lines contain the SiTi and DiSi and Ti are in the format of hh:mm.

     

    输出/Output

      The first line of output contains "YES" or "NO" indicating whether John can be present at every special ceremony. If it is "YES", output another N lines describing the staring time and finishing time of all the ceremonies.

     

    题解/solution

      把一个婚礼分成两个点,分别代表开始时间和结束时间。那么就把问题转换成了一个2-SAT问题。若两个点之间有冲突(也就是时间有重合)则连边。然后就是裸的2-SAT输出问题了。

     

    代码/Code

     

    const
      maxE=2000001;
      maxV=3001;
    
    type
      arr=record
        x,y,next:longint;
      end;
    
    var
      n,nm,num,tt,tk:longint;
      x,y,w,bel,ls,sta,state,dfn,low,du,color,con:array[0..maxV] of longint;
      v:array[0..maxV] of boolean;
      tu:array[0..maxE] of arr;
    
    function fd(o,p,t,k:longint):boolean;
    begin
      if (p<=t) or (k<=o) then exit(false);
      exit(true);
    end;
    
    procedure add(o,p:longint);
    begin
      inc(nm);
      with tu[nm] do
        begin
          x:=o; y:=p;
          next:=ls[o];
          ls[o]:=nm;
        end;
    end;
    
    function min(t,k:longint):longint;
    begin
      if t<k then exit(t);
      exit(k);
    end;
    
    procedure init;
    var
      i,j,h,m:longint;
      c1,c2,ct:char;
    begin
      readln(n);
      for i:=1 to n do
        begin
          read(c1,c2,ct); val(c1+c2,h);
          read(c1,c2,ct); val(c1+c2,m);
          x[i]:=h*60+m;
          read(c1,c2,ct); val(c1+c2,h);
          read(c1,c2,ct); val(c1+c2,m);
          y[i]:=h*60+m;
          readln(w[i]);
        end;
      for i:=1 to n-1 do
        for j:=i+1 to n do
          begin
            if fd(x[i],x[i]+w[i],x[j],x[j]+w[j]) then
              begin
                add(i,j+n);
                add(j,i+n);
              end;
            if fd(x[i],x[i]+w[i],y[j]-w[j],y[j]) then
              begin
                add(i,j);
                add(j+n,i+n);
              end;
            if fd(y[i]-w[i],y[i],x[j],x[j]+w[j]) then
              begin
                add(i+n,j+n);
                add(j,i);
              end;
            if fd(y[i]-w[i],y[i],y[j]-w[j],y[j]) then
              begin
                add(i+n,j);
                add(j+n,i);
              end;
          end;
    end;
    
    procedure dfs(x:longint);
    var
      i:longint;
    begin
      inc(num);
      dfn[x]:=num; low[x]:=num;
      inc(tt);
      sta[tt]:=x; v[x]:=true;
      i:=ls[x];
      while i>0 do
        with tu[i] do
          begin
            if dfn[y]=0 then
              begin
                dfs(y);
                low[x]:=min(low[x],low[y]);
              end else
              if v[y] then low[x]:=min(low[x],dfn[y]);
            i:=next;
          end;
      if dfn[x]=low[x] then
        begin
          inc(tk);
          repeat
            i:=sta[tt];
            dec(tt);
            v[i]:=false;
            bel[i]:=tk;
          until i=x;
        end;
    end;
    
    procedure tarjan;
    var
      i:longint;
    begin
      fillchar(v,sizeof(v),false);
      for i:=1 to n*2 do
        if dfn[i]=0 then dfs(i);
    end;
    
    procedure topsort;
    var
      head,tail,i:longint;
    begin
      head:=0; tail:=0;
      for i:=1 to tk do
        if du[i]=0 then
          begin
            inc(tail);
            state[tail]:=i;
          end;
      repeat
        inc(head);
        i:=ls[state[head]];
        while i>0 do
          with tu[i] do
            begin
              dec(du[y]);
              if du[y]=0 then
                begin
                  inc(tail);
                  state[tail]:=y;
                end;
              i:=next;
            end;
      until head>=tail;
    end;
    
    procedure blue(x:longint);
    var
      i:longint;
    begin
      color[x]:=-1;
      i:=ls[x];
      while i>0 do
        with tu[i] do
          begin
            if color[y]=0 then blue(y);
            i:=next;
          end;
    end;
    
    procedure red;
    var
      i:longint;
    begin
      for i:=1 to tk do
        if color[state[i]]=0 then
          begin
            color[state[i]]:=1;
            blue(con[state[i]]);
          end;
    end;
    
    procedure print;
    var
      i,t1,t2:longint;
    begin
      writeln('YES');
      for i:=1 to n do
        begin
          if color[bel[i]]=1 then
            begin
              t1:=x[i];
              t2:=x[i]+w[i];
            end else
            begin
              t1:=y[i]-w[i];
              t2:=y[i];
            end;
          if t1 div 60<10 then write(0);
          write(t1 div 60,':');
          if t1 mod 60<10 then write(0);
          write(t1 mod 60,' ');
          if t2 div 60<10 then write(0);
          write(t2 div 60,':');
          if t2 mod 60<10 then write(0);
          writeln(t2 mod 60);
        end;
    end;
    
    procedure main;
    var
      i:longint;
    begin
      for i:=1 to n do
        begin
          if bel[i]=bel[i+n] then
            begin
              writeln('NO');
              exit;
            end;
          con[bel[i]]:=bel[i+n];
          con[bel[i+n]]:=bel[i];
        end;
      fillchar(ls,sizeof(ls),0);
      for i:=1 to nm do
        with tu[i] do
          if bel[x]<>bel[y] then
            begin
              add(bel[y],bel[x]);
              inc(du[bel[x]]);
            end;
      topsort;
      red;
      print;
    end;
    
    begin
      init;
      tarjan;
      main;
    end.
    



  • 相关阅读:
    多维数组,转化为一维数组多种解决方案
    word-wrap与word-break的区别,以及无效情况
    重温前端基础之-js排序算法
    重温前端基础之-css浮动之怪异现象
    重温前端基础之-css浮动与清除浮动
    重温前端基础之-css盒模型
    C# 应用
    C# 应用
    C# 应用
    C# 应用
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9319680.html
Copyright © 2020-2023  润新知