您的位置:首页 > 其它

Pku 3207 Ikki's Story IV - Panda's Trick

2011-09-08 00:27 337 查看
题目:

Ikki'sStoryIV-Panda'sTrick

来源:

Pku3207

题目大意:

一个圆上有N个点,顺时针从0到N-1排列。给出M条线连接两个点,要么在圆外要么在圆内,判断给出的所有线段是否不规范相交。

Outputaline,either“
pandaistellingthetruth...
”(yes)or“
theevilpandaislyingagain
”(no)

数据范围:

n≤1,000,m≤500

样例:

42

01

32

pandaistellingthetruth...


做题思路:

把每个线段看成两个点,I代表在圆外,I'代表在圆外。

显然,本题要求的就是对于所有I和I'只取一个,问是否可以取完所有M组点。

所以就变成了一个简单的2-sat验证问题。

构图,若I和J相交,则I向J'连一条边,J'向I连一条边,I'向J连一条边,J向I'连一条边。

注:本题数据很弱,在我敲错的情况下都能过

知识点:

2-sat验证、kosaraju

type
edge=record
y,next:longint;
end;
//====================================================
var
a1,a2:array[0..1000010]ofedge;
first1,first2,q1,f,a,b:array[0..2020]oflongint;
time,tot1,tot2,n,m:longint;
//=========================================================
procedurebuild1(x,y:longint);
begin
inc(tot1);
a1[tot1].y:=y;
a1[tot1].next:=first1[x];
first1[x]:=tot1;
end;
//==================================================================
procedurebuild2(x,y:longint);
begin
inc(tot2);
a2[tot2].y:=y;
a2[tot2].next:=first2[x];
first2[x]:=tot2;
end;
//=================================================================
functionpd(x,l,r:longint):boolean;
begin
ifr<lthen
if(r<x)and(l>x)thenexit(true);
ifl<rthen
if(l<x)and(r>x)thenexit(true);
exit(false);
end;
//============================================================
procedureinit;
var
i,x1,x2,y1,y2,j,t:longint;
ch1,ch2:char;
begin
readln(n,m);
tot1:=0;tot2:=0;
fillchar(first1,sizeof(first1),0);
fillchar(first2,sizeof(first2),0);
fori:=1tomdo
readln(a[i],b[i]);
fori:=1tom-1do
forj:=i+1tomdo
begin
if(pd(a[i],a[j],b[j]))and(pd(b[i],b[j],a[j]))or{<如何判断是否交叉:一个点在这条直线(两点间),另一个点在另一边则交叉>}
(pd(b[i],a[j],b[j]))and(pd(a[i],b[j],a[j]))then
begin
build1(2*i-1,2*j);build2(2*j,2*i-1);{<两两连边>}
build1(2*j-1,2*i);build2(2*i,2*j-1);
build1(2*i,2*j-1);build2(2*j-1,2*i);
build1(2*j,2*i-1);build2(2*i-1,2*j);
end;

end;
end;
//===========================================================
proceduredfs1(x:longint);
var
t:longint;
begin
f[x]:=1;
t:=first1[x];
whilet>0do
begin
iff[a1[t].y]=0thendfs1(a1[t].y);
t:=a1[t].next;
end;
inc(time);
q1[time]:=x;
end;
//==========================================================
proceduredfs2(x:longint);
var
t:longint;
begin
f[x]:=time;
t:=first2[x];
whilet>0do
begin
iff[a2[t].y]=0thendfs2(a2[t].y);
t:=a2[t].next;
end;
end;
//==============================================================
procedurekosaraju;
var
i:longint;
begin
time:=0;
fillchar(f,sizeof(f),0);
fori:=1ton*2do
iff[i]=0thendfs1(i);
time:=0;
fillchar(f,sizeof(f),0);
fori:=n*2downto1do
iff[q1[i]]=0then
begin
inc(time);
dfs2(q1[i]);
end;
end;
//=======================================================
proceduremain;
var
i:longint;
begin
fori:=1to2*mdo
if(odd(i))and(f[2*i]=f[2*i-1])then
begin
writeln('theevilpandaislyingagain');
exit;
end;
writeln('pandaistellingthetruth...');
end;
//==========================================================
begin
init;
kosaraju;
main;
end.题目来源:http://poj.org/problem?id=3207
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: