Pku 3683 Priest John's Busiest Day

来源:互联网 发布:java用递归走迷宫 编辑:程序博客网 时间:2024/05/16 23:45

题目:

 Priest John's Busiest Day

来源:

 Pku 3683

题目大意:

 有N个区间(A,B),和一个值C。你可以选择使用(A,A+C)或(B-C,B)中一个区  间,使得所有选择出来的N个区间不相交,求方案。

数据范围:

 1 ≤ N ≤ 1000

样例:

 2
 08:00 09:00 30
 08:15 09:00 20
YES
08:00 08:30
08:40 09:00

做题思路:

 起初看到区间就茫然了,才发现原来就是其中的两段啊,坑。。

 时间表达换分钟,最后再换回来。

 设区间(A,B)分为I和I'两个区间。
 若I和J和J'相交,则I肯定不能选,从I向I'连一条边。
 若I仅和J相交,则I向J'连一条边,J向I'连一条边。
 若I仅和J'相交,则I向J连一条边,J'向I'连一条边。

 两个区间怎么确定呢?枚举呗

知识点:

 2-sat、kosaraju、枚举

type edge=record y,next:longint; end;var a1,a2:array[0..1000010]of edge; first1,first2,q1,q2,f,a,b,c,col:array[0..2020]oflongint; time,tot1,tot2,n:longint;//=========================================================procedure build1(x,y:longint);begin inc(tot1); a1[tot1].y:=y; a1[tot1].next:=first1[x]; first1[x]:=tot1;end;//==================================================================procedure build2(x,y:longint);begin inc(tot2); a2[tot2].y:=y; a2[tot2].next:=first2[x]; first2[x]:=tot2;end;//=================================================================function pd(li,ri,lj,rj:longint):boolean;begin if((lj<ri)and(rj>li))or((li<rj)and(ri>lj)) then exit(true); exit(false);end;//============================================================procedure init;var i,x1,x2,y1,y2,j,t:longint; ch1,ch2:char;begin readln(n); tot1:=0;tot2:=0; fillchar(first1,sizeof(first1),0); fillchar(first2,sizeof(first2),0); fori:=1 to n do{<读入并转成分钟>}  begin  read(ch1,ch2);  a[i]:=(ord(ch1)-ord('0'))*10+(ord(ch2)-ord('0'));  read(ch1,ch1,ch2);  a[i]:=a[i]*60+(ord(ch1)-ord('0'))*10+(ord(ch2)-ord('0'));  read(ch1,ch1,ch2);  b[i]:=(ord(ch1)-ord('0'))*10+(ord(ch2)-ord('0'));  read(ch1,ch1,ch2);  b[i]:=b[i]*60+(ord(ch1)-ord('0'))*10+(ord(ch2)-ord('0'));  read(ch1);readln(c[i]);  end; fori:=1 to n-1 do{<枚举每个区间与别的区间是否存在交集,存在则不连边>}  forj:=i+1 to n do  begin   x1:=i*2-1;x2:=x1+1;   y1:=j*2-1;y2:=y1+1;   t:=0;    ifpd(a[i],a[i]+c[i],a[j],a[j]+c[j]) then t:=1;    ifpd(a[i],a[i]+c[i],b[j]-c[j],b[j]) then     ift=0 then t:=2           else t:=3;   case t of    1:begin       build1(x1,y2);build1(y1,x2);       build2(y2,x1);build2(x2,y1);      end;    2:begin       build1(x1,y1);build1(y2,x2);       build2(y1,x1);build2(x2,y2);      end;    3:begin       build1(x1,x2);build2(x2,x1);      end;   end;   t:=0;    ifpd(b[i]-c[i],b[i],a[j],a[j]+c[j]) then t:=1;    ifpd(b[i]-c[i],b[i],b[j]-c[j],b[j]) then    ift=0 then t:=2            else t:=3;   case t of    1:begin        build1(x2,y2);build1(y1,x1);        build2(y2,x2);build2(x1,y1);       end;    2:begin        build1(x2,y1);build1(y2,x1);        build2(y1,x2);build2(x1,y2);       end;    3:begin        build1(x2,x1);build2(x1,x2);       end;   end;   end;end;//===========================================================procedure dfs1(x:longint);var t:longint;begin f[x]:=1; t:=first1[x]; whilet>0 do  begin   iff[a1[t].y]=0 then dfs1(a1[t].y);  t:=a1[t].next;  end; inc(time); q1[time]:=x;end;//==========================================================procedure dfs2(x:longint);var t:longint;begin f[x]:=time; t:=first2[x]; whilet>0 do  begin   iff[a2[t].y]=0 then dfs2(a2[t].y);  t:=a2[t].next;  end;end;//==============================================================procedure kosaraju;var i:longint;begin time:=0; fillchar(f,sizeof(f),0); fori:=1 to n*2 do  iff[i]=0 then dfs1(i); time:=0; fillchar(f,sizeof(f),0); fori:=n*2 downto 1 do  iff[q1[i]]=0 then  begin   inc(time);   q2[time]:=q1[i];   dfs2(q1[i]);   end;end;//========================================================procedure delete(x:longint);var t:longint;begin col[x]:=2; t:=first2[x]; whilet>0 do  begin   if(col[a2[t].y]=0)and(f[x]=f[a2[t].y]) then delete(a2[t].y);  t:=a2[t].next;  end;end;//========================================================procedure sat(x:longint);var t:longint;begin col[x]:=1; t:=first2[x]; whilet>0 do  begin   if(col[a2[t].y]=0)and(f[x]=f[a2[t].y]) then sat(a2[t].y);  t:=a2[t].next;  end; ifodd(x) then delete(x+1) else delete(x-1);end;//=========================================================procedure print(x,d:longint);{<把分钟转换成小时>}var t:longint;begin if d=1then  begin  t:=a[x] div 60;   ift<=9 then write(0);  write(t,':');  t:=a[x] mod 60;   ift<=9 then write(0);  write(t,' ');  inc(a[x],c[x]);  t:=a[x] div 60;   ift<=9 then write(0);  write(t,':');  t:=a[x] mod 60;   ift<=9 then write(0);  write(t);  dec(a[x],c[x]);  end else  begin  dec(b[x],c[x]);  t:=b[x] div 60;   ift<=9 then write(0);  write(t,':');  t:=b[x] mod 60;   ift<=9 then write(0);  write(t,' ');  inc(b[x],c[x]);  t:=b[x] div 60;   ift<=9 then write(0);  write(t,':');  t:=b[x] mod 60;   ift<=9 then write(0);  write(t);  end; writeln;end;//=========================================================procedure main;var i:longint;begin fori:=1 to n do  iff[2*i]=f[2*i-1] then  begin   writeln('NO');   exit;   end; fillchar(col,sizeof(col),0); fori:=time downto 1 do  ifcol[q2[i]]=0 then sat(q2[i]); writeln('YES'); fori:=1 to 2*n do  ifcol[i]=1 then   ifodd(i) then print((i+1) shr 1,1) else print((i+1) shr 1,0);end;//==========================================================begin init; kosaraju; main;end.
题目来源:http://poj.org/problem?id=3683