zoukankan      html  css  js  c++  java
  • 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.
    



  • 相关阅读:
    webpack4 plugins 篇
    webpack4 打包静态资源
    babel 7 简单指北
    JS: 深拷贝
    JS: 数组的循环函数
    async await 的执行
    redux
    TCP通信
    理解Javascript的原型和原型链
    「译」forEach循环中你不知道的3件事
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9319680.html
Copyright © 2011-2022 走看看