1. 程式人生 > >COGS——C2098. Asm.Def的病毒

COGS——C2098. Asm.Def的病毒

表情 src 輸出 天才 pan swap space pro logs

http://www.cogs.pro/cogs/problem/problem.php?pid=2098

★☆ 輸入文件:asm_virus.in 輸出文件:asm_virus.out 簡單對比
時間限制:1 s 內存限制:256 MB

【題目描述】

“這就是我們最新研制的,世界上第一種可持久化動態計算機病毒,‘創世紀’。”方教授介紹道。

“哦。”主席面無表情地點點頭。

“‘創世紀’無法真正殺死透明計算網絡,但是可以把它變成傻子。可惜透明計算網絡能輕松地辨認出病毒,所以我建議……”

“為什麽不偽裝呢?”Asm.Def說。

“當然不行,它比我們更懂偽裝。”

“我是說,把我們的病毒偽裝成殺毒軟件。”

方教授震驚地盯著Asm.Def看了一會。“你是個天才。”

技術分享

Asm.Def想把病毒偽裝成殺毒軟件,入侵透明計算網絡。透明計算網絡的文件結構是一棵N個節點的樹,每個病毒可以入侵一條路徑上的所有節點。但如果兩個病毒入侵了同一個節點,由於它們偽裝成了殺毒軟件,就會自相殘殺。Asm.Def不希望這樣的情況發生,所以他需要仔細制定入侵計劃。為此,他需要頻繁地詢問,兩條路徑是否經過同一個節點(即是否相交)。

【輸入格式】

第一行兩個整數N,Q。

接下來N-1行,每行兩個整數a,b,表示(a,b)是樹上的一條邊。

接下來Q行,每行四個整數s1,t1,s2,t2,表示詢問s1~t1的路徑是否與s2~t2的路徑相交。

【輸出格式】

對每個詢問,若相交則輸出一行”YES”,否則輸出一行”NO”。

【樣例輸入】

6 5
1 2
1 3
2 4
4 5
4 6
1 1 5 6
1 2 6 3
2 3 5 6
6 4 3 1
4 3 1 2

【樣例輸出】

NO
YES
NO
NO
YES

【提示】

N,Q<=1000.

1<=s1,t1,s2,t2<=N。

【來源】

 1 #include <algorithm>
 2 #include <cstdio>
 3 
 4 using namespace std;
 5 
 6 const int N(1000+15);
 7 int n,q,u,v;
 8 
 9 int head[N],sumedge;
10 struct Edge
11 {
12     int v,next;
13     Edge(int v=0,int next=0):
14         v(v),next(next){}
15 }edge[N<<1];
16 void ins(int u,int v)
17 {
18     edge[++sumedge]=Edge(v,head[u]);
19     head[u]=sumedge;
20 }
21 
22 int dad[N],size[N],deep[N],top[N];
23 void DFS(int x)
24 {
25     size[x]=1;deep[x]=deep[dad[x]]+1;
26     for(int i=head[x];i;i=edge[i].next)
27     {
28         int v=edge[i].v;
29         if(dad[x]==v) continue;
30         dad[v]=x; DFS(v); size[x]+=size[v];
31     }
32 }
33 void DFS_(int x)
34 {
35     int t=0; if(!top[x]) top[x]=x;
36     for(int i=head[x];i;i=edge[i].next)
37     {
38         int v=edge[i].v;
39         if(dad[x]!=v&&size[t]<size[v]) t=v;
40     }
41     if(t) top[t]=top[x],DFS_(t);
42     for(int i=head[x];i;i=edge[i].next)
43     {
44         int v=edge[i].v;
45         if(dad[x]!=v&&v!=t) DFS_(v);
46     }
47 }
48 int LCA(int x,int y)
49 {
50     for(;top[x]!=top[y];x=dad[top[x]])
51         if(deep[top[x]]<deep[top[y]]) swap(x,y);
52     return deep[x]<deep[y]?x:y;
53 }
54 
55 int main()
56 {
57     freopen("asm_virus.in","r",stdin);
58     freopen("asm_virus.out","w",stdout);
59     
60     scanf("%d%d",&n,&q);
61     for(int i=1;i<n;i++)
62         scanf("%d%d",&u,&v),ins(u,v),ins(v,u);
63     DFS(1); DFS_(1);
64     for(int uu,vv;q--;)
65     {
66         scanf("%d%d%d%d",&u,&v,&uu,&vv);
67         int lca=LCA(u,v),lcaa=LCA(uu,vv);
68         if(deep[lca]<deep[lcaa])
69             swap(lca,lcaa),swap(u,uu),swap(v,vv);
70         if(LCA(lca,uu)==lca||LCA(lca,vv)==lca)
71             puts("YES");
72         else puts("NO");
73     }
74     return 0;
75 }

COGS——C2098. Asm.Def的病毒