★☆ 輸入文件:asm_virus.in
輸出文件:asm_virus.out
簡單對比
時間限制:1 s 內存限制:256 MBios
「這就是咱們最新研製的,世界上第一種可持久化動態計算機病毒,‘創世紀’。」方教授介紹道。網絡
「哦。」主席面無表情地點點頭。spa
「‘創世紀’沒法真正殺死透明計算網絡,可是能夠把它變成傻子。惋惜透明計算網絡能輕鬆地辨認出病毒,因此我建議……」code
「爲何不假裝呢?」Asm.Def說。blog
「固然不行,它比咱們更懂假裝。」內存
「我是說,把咱們的病毒假裝成殺毒軟件。」get
方教授震驚地盯着Asm.Def看了一會。「你是個天才。」string
Asm.Def想把病毒假裝成殺毒軟件,入侵透明計算網絡。透明計算網絡的文件結構是一棵N個節點的樹,每一個病毒能夠入侵一條路徑上的全部節點。但若是兩個病毒入侵了同一個節點,因爲它們假裝成了殺毒軟件,就會自相殘殺。Asm.Def不但願這樣的狀況發生,因此他須要仔細制定入侵計劃。爲此,他須要頻繁地詢問,兩條路徑是否通過同一個節點(便是否相交)。it
第一行兩個整數N,Q。io
接下來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,這樣說也不是很準確。
咱們來這樣看
咱們看2 ,7與4 ,5顯然他們兩個的路徑上相交的,咱們來看,2 7的lca爲4 、4 5的lca爲1.這兩值並不相同啊,可是咱們能夠發現,若是這兩條路徑相交那麼這兩組lca中上深度深的那個lca必定與另外一組數其中一個值的lca必定爲那個深度深的lca。不信?!咱們來看這個圖,二、7的lca爲4,4 、5的lca爲1,這樣深度深的lca爲4,他與5的lca剛好是1,而且這兩組路徑相交。
代碼:
#include<cstdio> #include<vector> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define N 1100 using namespace std; vector<int>vec[N]; int n,m,x,y,q,p,root; int fa[N],top[N],deep[N],size[N]; int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f; } int lca(int x,int y) { for(;top[x]!=top[y];) { if(deep[top[x]]<deep[top[y]]) swap(x,y); x=fa[x]; } if(deep[x]>deep[y]) swap(x,y); return x; } int dfs(int x) { size[x]=1; deep[x]=deep[fa[x]]+1; for(int i=0;i<vec[x].size();i++) if(vec[x][i]!=fa[x]) { fa[vec[x][i]]=x; dfs(vec[x][i]); size[x]+=size[vec[x][i]]; } } int dfs1(int x) { int t=0; if(!top[x]) top[x]=x; for(int i=0;i<vec[x].size();i++) if(vec[x][i]!=fa[x]&&size[vec[x][i]]>size[t]) t=vec[x][i]; if(t) top[t]=top[x],dfs1(t); for(int i=0;i<vec[x].size();i++) if(vec[x][i]!=fa[x]&&vec[x][i]!=t) dfs1(vec[x][i]); } int main() { freopen("asm_virus.in","r",stdin); freopen("asm_virus.out","w",stdout); n=read(),m=read(); for(int i=1;i<n;i++) { x=read(),y=read();fa[y]=x; vec[x].push_back(y); vec[y].push_back(x); } dfs(1),dfs1(1); for(int i=1;i<=m;i++) { x=read(),y=read(),q=read(),p=read(); int Lca=lca(x,y),LCA=lca(q,p); //printf("%d %d\n",Lca,LCA); if(deep[Lca]<deep[LCA]) swap(Lca,LCA),swap(x,q),swap(y,p); if(lca(Lca,q)==Lca||lca(Lca,p)==Lca) printf("YES\n"); else printf("NO\n"); } return 0; }