日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

牛客网【每日一题】7月8日 Alliances

發(fā)布時間:2023/12/3 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客网【每日一题】7月8日 Alliances 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

來源:牛客網(wǎng)

文章目錄

    • 題目描述
    • 題解:
    • 代碼:

時間限制:C/C++ 5秒,其他語言10秒 空間限制:C/C++ 262144K,其他語言524288K 64bit IO Format: %lld

題目描述

樹國是一個有n個城市的國家,城市編號為1~n。連接這些城市的道路網(wǎng)絡(luò)形如一棵樹,
即任意兩個城市之間有恰好一條路徑。城市中有k個幫派,編號為1~k。每個幫派會占據(jù)一些城市,以進(jìn)行非法交易。有時幫派之間會結(jié)盟,這就使得城市更加不安全了。同一座城市中可能有多個幫派。
當(dāng)一些幫派結(jié)成聯(lián)盟時,他們會更加強(qiáng)大,同時也更加危險。他們所控制的城市數(shù)會顯著增加。具體地,一個聯(lián)盟控制的城市是聯(lián)盟中所有幫派所占據(jù)的城市,再加上這些城市兩兩之間路徑上的所有城市。
shy是樹國的市長,他想要選擇一個城市作為首都。在決定之前,他要先做一些調(diào)研。為此,他找來你幫他回答一些詢問,你能做到嗎?在每個詢問中,shy會選擇一個城市作為首都,同時會告訴你當(dāng)前活躍的幫派的集合。在這個詢問中,你只需要考慮給定的集合中的幫派,其他的幫派你可以當(dāng)作不存在。已知給定集合中的這些幫派結(jié)成了聯(lián)盟,shy希望抓獲聯(lián)盟中的人,以得到關(guān)于整個聯(lián)盟的一些信息。為此,他要找到被聯(lián)盟控制的所有城市中離首都最近的一座城市到首都的距離。有可能首都本身就被控制了,此時答案為0。請注意,詢問之間相互獨立,互不影響。

輸入描述:

輸入的第一行包含一個整數(shù)n,代表樹國中的城市數(shù)。 接下來n?1行,每行包含兩個整數(shù)u和v,代表城市u和v之間存在一條道路。
接下來一行包含一個整數(shù)k,代表樹國中的幫派數(shù)。
接下來k行,每行描述一個幫派。第i行的第一個整數(shù)c[i]代表第i個幫派占據(jù)的城市數(shù),接下來c[i]個整數(shù),代表被第i個幫派占據(jù)的城市。
接下來一行包含一個整數(shù)Q,代表詢問數(shù)。
接下來Q行,每行描述一個詢問。每行的前兩個整數(shù)V和t[i]代表本次詢問中的首都與需要考慮的幫派集合的大小。接下來t[i]個整數(shù)代表本次詢問中需要考慮的幫派。.

輸出描述:

對于每個詢問,輸出一行,包含一個整數(shù),代表詢問的答案。

示例1
輸入

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

輸出

2 1 1

備注:

對于30%的數(shù)據(jù),1≤n,k,Q≤1000, 1≤每個幫派占據(jù)城市數(shù)之和≤1000, 1≤每個詢問中考慮的幫派數(shù)之和≤1000

對于60%的數(shù)據(jù),1≤n,k,Q≤100000, 1≤每個幫派占據(jù)城市數(shù)之和≤100000, 1≤每個詢問中考慮的幫派數(shù)之和≤100000

對于100%的數(shù)據(jù),1≤n,k,Q≤500000, 1≤每個幫派占據(jù)城市數(shù)之和≤500000, 1≤每個詢問中考慮的幫派數(shù)之和≤500000

題解:

第一反應(yīng)lca,最近好多l(xiāng)ca的題
題目本質(zhì)就是求一個點(即題目中的首都)到lca(x,y)上的點(即被控制的城市)的最短路徑
被控制的城市其實就形成了一個子樹
分情況討論:
1.城市不在被控制的子樹里面(如圖)
紫色是城市,橙色是被控制子樹,那距離就是首都到子樹的距離
sum=dep[首都]+dep[lca(城市x)]-dep[lca(城市x,首都)]
城市x就是lca(x,y)的值(x和y就是題目所給的幫派)

2.首都被控制
首都被控制分為直接控制(幫派點為首都)
或間接控制(首都在幫派之間的線路上)
那距離就是0


3.首都沒被控制,但是首都在被控制的子樹中
(首都的前驅(qū)被控制,后繼沒被控制)
對于這種情況我們就要找首都的的前驅(qū)后繼點,這樣好判斷距離
可以用dfs序,因為dfs序就保存著各個點的順序
然后可以用二分來降低復(fù)雜度
如果首都到LCA的路徑上存在一個點x(x被占領(lǐng)),x!=lca,那么答案就是首都到最近一個符合這個條件的點

lca詳細(xì)講解
dfs序詳細(xì)講解
為什么這些知識點我都會,但是我就不會做題。。哭o(╥﹏╥)o

代碼:

寫完再加上。。。(最近有點懶)


好吧我放棄了,寫完一直改,一直wa,難受自閉了
借鑒的大佬的代碼

#include<bits/stdc++.h> using namespace std; typedef long long LL; const int MAX_N=1e6+20; const int DEG=20; const int INF=0x3f3f3f3f; const LL MOD=1e9+7; int T; int N; //鏈?zhǔn)角跋蛐谴暹?/span> int head[MAX_N],tot; struct Edge{int to,nxt; }edge[MAX_N*2]; void addedge(int u,int v){edge[tot].to=v;edge[tot].nxt=head[u];head[u]=tot++; } void init(){tot=0;memset(head,-1,sizeof(head)); }//求LCA int fa[MAX_N][DEG]; int deg[MAX_N]; void BFS(int root){queue<int>que;deg[root]=0;fa[root][0]=root;que.push(root);while(!que.empty()){int tmp=que.front();que.pop();for(int i=1;i<DEG;i++){fa[tmp][i]=fa[fa[tmp][i-1]][i-1];}for(int i=head[tmp];i!=-1;i=edge[i].nxt){int v=edge[i].to;if(v==fa[tmp][0])continue;deg[v]=deg[tmp]+1;fa[v][0]=tmp;que.push(v);}} } int LCA(int u,int v){if(deg[u]>deg[v])swap(u,v);int hu=deg[u],hv=deg[v];int tu=u,tv=v;for(int det=hv-hu,i=0;det;det>>=1,i++){if(det&1)tv=fa[tv][i];}if(tu==tv)return tu;for(int i=DEG-1;i>=0;i--){if(fa[tu][i]==fa[tv][i])continue;tu=fa[tu][i];tv=fa[tv][i];}return fa[tu][0];} //求DFS序 int dfsn[MAX_N]; int pos[MAX_N]; int dfst=0; void DFS(int v,int fa){dfsn[v]=++dfst;pos[dfst]=v;for(int i=head[v];i!=-1;i=edge[i].nxt){int u=edge[i].to;if(u==fa)continue;DFS(u,v);} } int dis(int u,int v){int res=deg[u]+deg[v]-2*deg[LCA(u,v)];return res; } //lc存每一個幫派的LCA //g存每一個幫派的DFS序 int lc[MAX_N]; vector<int> g[MAX_N]; int n; int u,v; void input(){} int t[MAX_N]; int main(){init();scanf("%d",&n);for(int i=1;i<n;i++){scanf("%d%d",&u,&v);addedge(u,v);addedge(v,u);}BFS(1);DFS(1,-1);int k;scanf("%d",&k);for(int i=1;i<=k;i++){int c,x;scanf("%d",&c);for(int j=1;j<=c;j++){scanf("%d",&x);if(j==1)lc[i]=x;else lc[i]=LCA(lc[i],x);g[i].push_back(dfsn[x]);}sort(g[i].begin(),g[i].end());//cout<<lc[i]<<endl;}//cout<<"****"<<endl;int q,u,cnt;scanf("%d",&q);while(q--){scanf("%d%d",&u,&cnt);for(int i=1;i<=cnt;i++){scanf("%d",&t[i]);}int lca=lc[t[1]];for(int i=2;i<=cnt;i++)lca=LCA(lca,lc[t[i]]);if(LCA(lca,u)!=lca){printf("%d\n",dis(lca,u));continue;}int ans=INF;for(int i=1;i<=cnt;i++){int tmp=t[i];auto p=lower_bound(g[tmp].begin(),g[tmp].end(),dfsn[u]);if(p!=g[tmp].end()){ans=min(ans,dis(u,LCA(u,pos[*p])));}if(p!=g[tmp].begin()){ans=min(ans,dis(u,LCA(u,pos[*prev(p)])));}}printf("%d\n",ans);}}

總結(jié)

以上是生活随笔為你收集整理的牛客网【每日一题】7月8日 Alliances的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。