解题报告 poj 3207
1.????????題目
POJ?3207
2.????????題目實質
平面上,一個圓,圓的邊上按順時針放著n個點。現在要連m條邊,比如a,b,那么a到b可以從圓的內部連接,也可以從圓的外部連接。問能不能連接這m條邊,使這些邊都不相交。(比如兩條邊分別是1-2,2-3,則可以連接。若有三條邊分別時1-5,2-6,3-7則一定會出現相交)。
3.????????算法
2-SAT。(NOI)
題意可能剛開始不是很好理解,比如1?5連邊,2,6連邊,由于點是順序排列的,一畫圖就可以發現,這兩條邊必須一個從圓外面連,一個從內部連,否則就會相交。如果再加入3?7這條邊,那么就必須相交了。
這樣,就可以轉化成標準的2-sta問題:
1:每個邊看成2個點:分別表示在內部連接和在外部連接,只能選擇一個。計作點i和點i'
2:如果兩條邊i和j必須一個畫在內部,一個畫在外部(一個簡單判斷就可以)
那么連邊:
i->j’,?表示i畫內部的話,j只能畫外部,即j’
j->i’,同理
i’->j,同理
j’->i,同理
然后就是2-sat算法了,tarjan一下,如果有i和i'同屬于一個強聯通,返回false,否則就成立。
4.????????注意事項
對于?NOIP?的孩子們來說,?tarjan?素超綱滴。
5.????????代碼
2-sat?(ZSZ)
program?fot;
var?belong,l,r:array[0..500010]?of?longint;
????instack:array[0..500010]?of?boolean;
????low,dfn,stack,f:array[0..500010]?of?longint;
????e:Array[0..500010]?of?record
??????y,n:longint;
????end;
????o,i,n,top,j,m,time,number,q,z:longint;
????boo:boolean;
function?min(a,b:longint):longint;
begin
??if?a<b?then?exit(a)?else?exit(b);
end;
procedure?swap(var?a,b:longint);
var?c:longint;
begin
??c:=a;a:=b;b:=c;
end;
procedure?add(a,b:longint);
begin
??inc(o);
??e[o].y:=b;
??e[o].n:=f[a];
??f[a]:=o;
end;
procedure?tarjan(x:longint);
var?t:longint;
begin
??inc(time);
??dfn[x]:=time;
??low[x]:=time;
??inc(top);
??instack[x]:=true;
??stack[top]:=x;
??t:=f[x];
??while?t<>0?do
????begin
??????if?(dfn[e[t].y]=0)?then
????????begin
??????????tarjan(e[t].y);
??????????low[x]:=min(low[x],low[e[t].y]);
????????end
??????else
??????if?instack[e[t].y]=true?then
????????low[x]:=min(low[x],dfn[e[t].y]);
??????t:=e[t].n;
????end;
??if?dfn[x]=low[x]?then
????begin
??????inc(number);
??????repeat
????????t:=stack[top];
????????dec(top);
????????instack[t]:=false;
????????belong[t]:=number;
??????until?t=x;
????end;
end;
begin
??readln(n,m);
??for?i:=?1?to?m?do
????begin
??????readln(l[i],r[i]);
??????if?(r[i]<l[i])?then?swap(r[i],l[i]);
????end;
??o:=0;
??fillchar(e,sizeof(e),0);
??fillchar(f,sizeof(f),0);
??fillchar(dfn,sizeof(dfn),0);
??fillchar(stack,sizeof(stack),0);
??fillchar(low,sizeof(low),0);
??fillchar(belong,sizeof(belong),0);
??fillchar(instack,sizeof(instack),false);
??for?i:=?1?to?m?do
????for?j:=?i+1?to?m?do
??????begin
????????if?((l[i]>l[j])and(l[i]<r[j])and(r[i]>r[j]))or
????????((l[j]>l[i])and(l[j]<r[i])and(r[j]>r[i]))?then
??????????begin
????????????add(i,j+m);
????????????add(j+m,i);
????????????add(j,i+m);
????????????add(i+m,j);
??????????end;
??????end;
??top:=0;
??for?i:=?1?to?2*m?do
????if?dfn[i]=0?then?tarjan(i);
??boo:=true;
??for?i:=?1?to?m?do
????if?belong[i]=belong[i+m]?then
??????begin
????????boo:=false;
????????break;
??????end;
??if?boo=true?then?writeln('panda?is?telling?the?truth...')
??else?writeln('the?evil?panda?is?lying?again');
end.
?
轉載于:https://www.cnblogs.com/SueMiller/archive/2011/10/17/2215523.html
總結
以上是生活随笔為你收集整理的解题报告 poj 3207的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手持GPS坐标系统的转换与应用
- 下一篇: 怎么自己安装win10系统 如何在电脑上