树国是一个有n个城市的国家,城市编号为1∼n。连接这些城市的道路网络形如一棵树,
即任意两个城市之间有恰好一条路径。城市中有k个帮派,编号为1∼k。每个帮派会占据一些城市,以进行非法交易。有时帮派之间会结盟,这就使得城市更加不安全了。同一座城市中可能有多个帮派。
当一些帮派结成联盟时,他们会更加强大,同时也更加危险。他们所控制的城市数会显著增加。具体地,一个联盟控制的城市是联盟中所有帮派所占据的城市,再加上这些城市两两之间路径上的所有城市。
shy是树国的市长,他想要选择一个城市作为首都。在决定之前,他要先做一些调研。为此,他找来你帮他回答一些询问,你能做到吗?在每个询问中,shy会选择一个城市作为首都,同时会告诉你当前活跃的帮派的集合。在这个询问中,你只需要考虑给定的集合中的帮派,其他的帮派你可以当作不存在。已知给定集合中的这些帮派结成了联盟,shy希望抓获联盟中的人,以得到关于整个联盟的一些信息。为此,他要找到被联盟控制的所有城市中离首都最近的一座城市到首都的距离。有可能首都本身就被控制了,此时答案为0。请注意,询问之间相互独立,互不影响。
 

输入描述:

输入的第一行包含一个整数n,代表树国中的城市数。
接下来n−1行,每行包含两个整数u和v,代表城市u和v之间存在一条道路。
接下来一行包含一个整数k,代表树国中的帮派数。
接下来k行,每行描述一个帮派。第i行的第一个整数c[i]代表第i个帮派占据的城市数,接下来c[i]个整数,代表被第i个帮派占据的城市。
接下来一行包含一个整数Q,代表询问数。
接下来Q行,每行描述一个询问。每行的前两个整数V和t[i]代表本次询问中的首都与需要考虑的帮派集合的大小。接下来t[i]个整数代表本次询问中需要考虑的帮派。.

输出描述:

对于每个询问,输出一行,包含一个整数,代表询问的答案。
示例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%的数据,1≤n,k,Q≤1000, 1≤每个帮派占据城市数之和≤1000, 1≤每个询问中考虑的帮派数之和≤1000  对于60%的数据,1≤n,k,Q≤100000, 1≤每个帮派占据城市数之和≤100000, 1≤每个询问中考虑的帮派数之和≤100000 对于100%的数据,1≤n,k,Q≤500000, 1≤每个帮派占据城市数之和≤500000, 1≤每个询问中考虑的帮派数之和≤500000
分析:首先,联盟或者帮派是形成一棵树的;
   如果首都如果向上不能到达树,那么直接输出树根与首都距离;
   否则首都一定向上到达树里某个点;
   为了找出这个点,利用dfs序,求出首都附近两个点,分别求与首都lca,距离取最小;
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <bitset>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <cassert>
#include <ctime>
#define rep(i,m,n) for(i=m;i<=(int)n;i++)
#define inf 0x3f3f3f3f
#define mod 998244353
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define sys system("pause")
#define ls (rt<<1)
#define rs (rt<<1|1)
#define all(x) x.begin(),x.end()
const int maxn=5e5+;
const int N=2e5+;
using namespace std;
ll gcd(ll p,ll q){return q==?p:gcd(q,p%q);}
ll qmul(ll p,ll q,ll mo){ll f=;while(q){if(q&)f=(f+p)%mo;p=(p+p)%mo;q>>=;}return f;}
ll qpow(ll p,ll q,ll mo){ll f=;while(q){if(q&)f=f*p%mo;p=p*p%mo;q>>=;}return f;}
int n,m,k,t,dfn[maxn],st[maxn],anc[maxn],dep[maxn],fa[][maxn],tot,cnt,head[maxn];
vi p[maxn];
struct node
{
int to,nxt;
}e[maxn<<];
void add(int x,int y)
{
e[cnt].to=y;
e[cnt].nxt=head[x];
head[x]=cnt++;
}
set<int>bl[maxn];
void dfs(int x,int y)
{
int i;
dfn[++tot]=x;
st[x]=tot;
dep[x]=dep[y]+;
for(i=;fa[i-][fa[i-][x]];i++)
{
fa[i][x]=fa[i-][fa[i-][x]];
}
for(i=head[x];i!=-;i=e[i].nxt)
{
int z=e[i].to;
if(z==y)continue;
fa[][z]=x;
dfs(z,x);
}
}
int lca(int x,int y)
{
int i;
if(dep[x]<dep[y])swap(x,y);
for(i=;i>=;i--)if(dep[fa[i][x]]>=dep[y])x=fa[i][x];
if(x==y)return x;
for(i=;i>=;i--)
{
if(fa[i][x]!=fa[i][y])
{
x=fa[i][x];
y=fa[i][y];
}
}
return fa[][x];
}
int main(){
int i,j;
scanf("%d",&n);
rep(i,,n)head[i]=-;
rep(i,,n-)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
scanf("%d",&m);
rep(i,,m)
{
scanf("%d",&j);
while(j--)scanf("%d",&k),p[k].pb(i);
}
dfs(,);
rep(i,,n)
{
rep(j,,p[i].size()-)
{
if(anc[p[i][j]]==)anc[p[i][j]]=i;
else anc[p[i][j]]=lca(anc[p[i][j]],i);
bl[p[i][j]].insert(st[i]);
}
}
int q;
scanf("%d",&q);
while(q--)
{
int cap,fa=-,pr=-,nt=-;
scanf("%d",&cap);
scanf("%d",&j);
while(j--)
{
scanf("%d",&k);
auto x=bl[k].lower_bound(st[cap]);
if(x!=bl[k].end())
{
if(nt==-)nt=*x;
else nt=min(nt,*x);
}
if(x!=bl[k].begin()&&(x==bl[k].end()||*x>st[cap]))--x;
if(x!=bl[k].end()&&*x<=st[cap])
{
if(pr==-)pr=*x;
else pr=max(pr,*x);
}
if(fa==-)fa=anc[k];
else fa=lca(anc[k],fa);
}
int x_fa=lca(fa,cap);
if(x_fa==cap||x_fa!=fa)printf("%d\n",dep[fa]+dep[cap]-*dep[x_fa]);
else
{
int ret1=1e9,ret2=1e9;
if(pr!=-)pr=dfn[pr],ret1=dep[cap]-dep[lca(pr,cap)];
if(nt!=-)nt=dfn[nt],ret2=dep[cap]-dep[lca(nt,cap)];
printf("%d\n",min(ret1,ret2));
}
}
return ;
}

Alliances的更多相关文章

  1. Wannafly模拟赛2 C alliances(dfs序+二分)

    题目 https://www.nowcoder.com/acm/contest/4/C 题意 由n个点组成一个树,有m个帮派,每个帮派由一些个点组成,这些点以及它们两两路径上的所有点都属于该帮派的管辖 ...

  2. 牛客 4C Alliances (dfs序)

    大意: 给定树, 有$k$个帮派, 第$i$个帮派所占据点为$c_i$, 以及$c_i$两两相连路径上的所有点. 一个点可能被多个帮派占领. $q$个询问, 第$i$个询问给定$t_i$个帮派, 给定 ...

  3. #英文#品读中国城市个性——最好的和最坏的&当东方遇到西方

    冒险家的乐园 a playground of risk 实现发财梦 realize one's dreams of wealth 道德沦丧,堕落 moral deprivation 租界 foreig ...

  4. 魔兽争霸3 replay 格式

    ******************************************************************************* * WarCraft III Repla ...

  5. The Sorrows of Young Werther

    The Sorrows of Young Werther J.W. von Goethe Thomas Carlyle and R.D. Boylan Edited by Nathen Haskell ...

  6. Python统计词频的几种方式

    语料 text = """My fellow citizens: I stand here today humbled by the task before us, gr ...

  7. List of regional organizations by population

    https://baike.baidu.com/item/国际组织/261053?fr=aladdin 经济文化类组织(非政府组织) 创行 狮子会 全球青年领导力联盟 乐施会 政治类组织 欧洲联盟(欧 ...

  8. 奥巴马(Obama)获胜演讲全文[中英对照]+高清视频下载

    http://www.amznz.com/obama-speech/如果还有人对美国是否凡事都有可能存疑,还有人怀疑美国奠基者的梦想在我们所处的时代是否依然鲜活,还有人质疑我们的民主制度的力量,那么今 ...

  9. Distributed Management Task Force----分布式管理任务组

    http://baike.baidu.com/link?url=Y9HGLs8Qj6pXbbgY6xPdfiGDsQO8Eu1e80B4giQtQ_hAfGNF59byxnLoERYri4Duw7Gw ...

随机推荐

  1. Kaggle "Microsoft Malware Classification Challenge"——就是沙箱恶意文件识别,有 Opcode n-gram特征 ASM文件图像纹理特征 还有基于图聚类方法

    使用图聚类方法:Malware Classification using Graph Clustering 见 https://github.com/rahulp0491/Malware-Classi ...

  2. getElementByTagName的使用

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. LuoguP4246 [SHOI2008]堵塞的交通

    https://zybuluo.com/ysner/note/1125078 题面 给一个网格,每次把相邻两点连通性改为\(1\)或\(0\),询问两点是否联通. 解析 线段树神题... 码量巨大,细 ...

  4. Eclipse自定义HTML5,JSP模板

    原文:http://blog.csdn.net/xz2585458279/article/details/78833893 我们知道在MyEclipse里面编写的html和jsp模板并不符合html5 ...

  5. Java基础学习经验分享

    很多人学习Java,尤其是自学的人,在学习的过程中会遇到各种各样的问题以及难点,有时候卡在一个点上可能需要很长时间,因为你在自学的过程中不知道如何去掌握和灵活运用以及该注意的点.下面我整理了新手学习可 ...

  6. JavaScript--关闭窗口(window.close)

    close()关闭窗口 用法: window.close(); //关闭本窗口 或 <窗口对象>.close(); //关闭指定的窗口 例如:关闭新建的窗口. <script typ ...

  7. org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException。

    jdk1.8环境tomcat运行项目报错, org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException.解决方法:更改jdk1.7

  8. wait、notify、notifyAll实现线程间通信

    在Java中,可以通过配合调用Object对象的wait()方法和notify()方法或notifyAll()方法来实现线程间的通信.在线程中调用wait()方法,将阻塞等待其他线程的通知(其他线程调 ...

  9. Android 自己搭建一个直播系统吧

    服务端用 SRS(Simple Rtmp Server),在这里下载simple-rtmp-server需要Linux系统最好是Ubuntu,装个Ubuntu虚拟机就行了在Linux里,解压缩SRS ...

  10. Android开发初体验

    本文通过开发一个应用来学习Android基本概念及构成应用的UI组件. 开发的应用名叫GeoQuiz,它能给出一道道地理知识问题.用户点击true或false按钮回答问题,应用即时做出反馈 第一步请先 ...