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

COGS 2098. Asm.Def的病毒

head 結構 是個 pro out 是我 printf 計劃 技術

★☆ 輸入文件: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。

【來源】

在此鍵入。

倍增求LCA

屠龍寶刀點擊就送

#include <ctype.h>
#include <cstdio>
#define M 1005

void read(int &x)
{
    x=0;
    bool f=0;
    char ch=getchar();
    while(!isdigit(ch)) {if(ch==-) f=1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-0;ch=getchar();}
    x=f?(~x)+1:x;
}
struct node
{
    int next,to;
    node(int next=0,int to=0) :next(next),to(to){}
}edge[M<<2];
int head[M],cnt,dad[M][25],dep[M],N,Q;
void add(int u,int v)
{
    edge[++cnt]=node(head[u],v);
    head[u]=cnt;
}
void dfs(int x)
{
    dep[x]=dep[dad[x][0]]+1;
    for(int i=0;dad[x][i];i++)
    dad[x][i+1]=dad[dad[x][i]][i];
    for(int i=head[x];i;i=edge[i].next)
    {
        if(dad[x][0]!=edge[i].to)
        {
            dad[edge[i].to][0]=x;
            dfs(edge[i].to);
        }
    }
}
int max(int a,int b) {return a>b?a:b;}
void swap(int &x,int &y)
{
    int tmp=y;
    y=x;
    x=tmp;
}
int lca(int x,int y)
{
    if(dep[x]>dep[y]) swap(x,y);
    for(int i=20;i>=0;i--)
    if(dep[dad[y][i]]>=dep[x]) y=dad[y][i];
    if(x==y) return x;
    for(int i=20;i>=0;i--)
    if(dad[x][i]!=dad[y][i]) x=dad[x][i],y=dad[y][i];
    return dad[x][0];
}
int main()
{
    freopen("asm_virus.in","r",stdin);
    freopen("asm_virus.out","w",stdout);
    read(N);
    read(Q);
    for(int x,y,i=1;i<N;i++)
    {
        read(x);
        read(y);
        add(x,y);
        add(y,x);
    }
    dfs(1);
    for(int a,b,c,d;Q--;)
    {
        read(a);read(b);
        read(c);read(d);
        int maxn=0;
        maxn=max(lca(a,b),lca(c,d));
        if(lca(a,c)>=maxn||lca(a,d)>=maxn||lca(b,c)>=maxn||lca(b,d)>=maxn) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

COGS 2098. Asm.Def的病毒