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.
    



  • 相关阅读:
    在 tornado 中异步无阻塞的执行耗时任务
    django在nginx uwsgi和tornado异步方案在项目中的体验
    使用tornado让你的请求异步非阻塞
    转:Parameter Server 详解
    转:复杂网络分析总结
    从SDCard获取的图片按分辨率处理的方法
    胡振亮:原来这就是非常多站点百度权重做不上去的原因
    c语言函数---I
    [LeetCode] Single Number III
    hdu 5389 Zero Escape (dp)
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9319680.html
Copyright © 2011-2022 走看看