[SDOI2018]战略游戏
题目描述
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> #define N 200009 using namespace std; typedef long long ll; int dfn[N],head[N],tot,dis[N],n,low[N],ans,num,st[N],top,rbs[N],a[N]; bool vis[N]; inline ll rd(){ll x=0;char c=getchar();bool f=0;while(!isdigit(c)){if(c=='-')f=1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}return f?-x:x; } struct edge{int n,to;}e[N<<1]; inline void add(int u,int v){e[++tot].n=head[u];e[tot].to=v;head[u]=tot;} vector<int>vec[N],ed[N]; inline bool cmp(int a,int b){return dfn[a]<dfn[b];} struct LCA{ int top[N],size[N],son[N],fa[N],deep[N]; void clear(){memset(deep,0,sizeof(deep));memset(top,0,sizeof(top));memset(son,0,sizeof(son));memset(fa,0,sizeof(fa));} void dfs(int u){size[u]=1;dis[u]=dis[fa[u]]+(u<=n);for(int i=0;i<vec[u].size();++i){int v=vec[u][i];fa[v]=u;deep[v]=deep[u]+1;dfs(v);size[u]+=size[v];if(size[v]>size[son[u]])son[u]=v;} } void dfs2(int u){dfn[u]=++dfn[0];if(!top[u])top[u]=u;if(son[u])top[son[u]]=top[u],dfs2(son[u]);for(int i=0;i<vec[u].size();++i){int v=vec[u][i];if(v!=fa[u]&&v!=son[u])dfs2(v);} } inline int getlca(int u,int v){while(top[u]!=top[v]){if(deep[top[u]]<deep[top[v]])swap(u,v);u=fa[top[u]];}return deep[u]<deep[v]?u:v; } }lca; void tarjan(int u,int fa){dfn[u]=low[u]=++dfn[0];vis[u]=1;st[++top]=u;for(int i=head[u];i;i=e[i].n)if((i^fa)!=1){int v=e[i].to;if(dfn[v]>dfn[u])continue;if(!dfn[v]){tarjan(v,i);low[u]=min(low[u],low[v]);}else if(vis[v])low[u]=min(low[u],dfn[v]);if(dfn[u]==low[v]){++num;vec[u].push_back(num);//cout<<u<<" "<<num<<endl;while(st[top]!=v){vec[num].push_back(st[top]);//cout<<num<<" "<<st[top]<<endl;vis[st[top]]=0;top--;}vec[num].push_back(v);vis[v]=0;top--;//cout<<num<<" "<<v<<endl; }if(low[v]>dfn[u]){vec[u].push_back(v);top--;vis[v]=0;}} } void dfs(int u){for(int i=0;i<ed[u].size();++i){int v=ed[u][i];dfs(v);ans+=dis[v]-dis[u]; if(vis[v]&&v<=n)ans--;} } inline void init(){tot=1;top=0;memset(head,0,sizeof(head));memset(dfn,0,sizeof(dfn));memset(dis,0,sizeof(dis));lca.clear(); } inline void solve(){n=rd();int m=rd();int u,v;init();for(int i=1;i<=m;++i){u=rd();v=rd();add(u,v);add(v,u);} num=n;tarjan(1,0);memset(dfn,0,sizeof(dfn));top=0;lca.dfs(1);lca.dfs2(1);memset(vis,0,sizeof(vis));int q=rd();while(q--){int s=rd();ans=0;for(int i=1;i<=s;++i)a[i]=rd(),vis[a[i]]=1;sort(a+1,a+s+1,cmp);st[top=1]=rbs[rbs[0]=1]=a[1];int root=a[1];for(int i=2;i<=s;++i){int x=a[i];//cout<<x<<"guiu"<<endl;int l=lca.getlca(x,st[top]);if(l==st[top]){st[++top]=x;rbs[++rbs[0]]=x;continue;}while(top>1){int xx=st[top],yy=st[top-1];if(dfn[yy]<=dfn[l]){ed[l].push_back(xx);//cout<<l<<" "<<xx<<endl;top--;break;}ed[yy].push_back(xx);top--;//cout<<yy<<" "<<xx<<endl; }if(dfn[l]<dfn[st[top]]){if(dfn[l]<dfn[root])root=l;// cout<<l<<" "<<st[top]<<endl;ed[l].push_back(st[top]);top--;}if(l!=st[top])st[++top]=l,rbs[++rbs[0]]=l;st[++top]=x;rbs[++rbs[0]]=x; }while(top>1){// cout<<st[top-1]<<" "<<st[top]<<endl;ed[st[top-1]].push_back(st[top]);top--;}if(!vis[root]&&root<=n)ans++;dfs(root);printf("%d\n",ans);while(rbs[0]){int x=rbs[rbs[0]];vis[x]=0;ed[x].clear();rbs[0]--;} } for(int i=1;i<=num;++i)vec[i].clear(); } int main(){int T=rd();while(T--)solve();return 0; }
这里的圆方树不能随便的建,只能对每个点双开一个。、
具体建法为:对于非点双内的边,直接连,并且弹栈。
if(low[v]>dfn[u]){vec[u].push_back(v);top--;vis[v]=0;}
对于每个割顶,新开一个节点,然后边弹栈边连边。
if(dfn[u]==low[v]){++num;vec[u].push_back(num);while(st[top]!=v){vec[num].push_back(st[top]);vis[st[top]]=0;top--;}vec[num].push_back(v);vis[v]=0;top--;}
而且我们对于每个点双都只能算一次,为了避免算重,我们需要特判一下。
if(dfn[v]>dfn[u])continue
转载于:https://www.cnblogs.com/ZH-comld/p/10384724.html
[SDOI2018]战略游戏相关推荐
- LuoguP4606 [SDOI2018]战略游戏
LuoguP4606 [SDOI2018]战略游戏 题目描述 题目描述 省选临近,放飞自我的小 QQ 无心刷题,于是怂恿小 CC 和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由 nn 个城市 ...
- [BZOJ5329][Sdoi2018]战略游戏 圆方树+虚树
5329: [Sdoi2018]战略游戏 Time Limit: 30 Sec Memory Limit: 512 MB Submit: 174 Solved: 109 [Submit][Stat ...
- BZOJ5329: [SDOI2018]战略游戏——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5329 https://www.luogu.org/problemnew/show/P4606 省选 ...
- BZOJ5329:[SDOI2018]战略游戏(圆方树,虚树)
Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...
- [BZOJ5329][SDOI2018]战略游戏
bzoj luogu Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任 ...
- Luogu4606 SDOI2018 战略游戏 圆方树、虚树、链并
传送门 弱化版 考虑到去掉一个点使得存在两个点不连通的形式类似割点,不难想到建立圆方树.那么在圆方树上对于给出的关键点建立虚树之后,我们需要求的就是虚树路径上所有圆点的数量减去关键点的数量. 因为没有 ...
- 【题解】SDOI2018战略游戏
被CNST的大小卡了好久.一定要开到18呀-- 首先,遇到这种带各种各样环的图先考虑是不是可以建立圆方树,在圆方树上求出答案.然后转化为圆方树之后,我们就将图转化到了树上.答案非常的明显:只要一个圆点 ...
- P4606 [SDOI2018]战略游戏
[题意] 给出一个无向图,q次询问,每次给定一个点集s代表占领点,问有多少个未被占领的点可以作为点集s中两个点u,v的割点 [分析] 首先,先建立圆方树,问题转化为能包含 给定点集 的最小连通块的 圆 ...
- [SDOI2018]战略游戏 圆方树+虚树
Description 给T组数据. 每组数据给你一个n个点的无向图,保证图联通,给q个询问. 每个询问给k个节点,问每一次询问中,求有多少个点在断掉他之后可以使图中两个点不连通. Sample In ...
最新文章
- 2022 AI趋势8大预测!
- [转载]offsetHeight , clientHeight, scrollHeight 区别
- c++笔试题两道,求解当中一道
- [Google Guava] 7-原生类型
- 汽车车牌识别系统(六)-- 项目中的各个文件解析
- 算法优化:最大字段和,双指针遍历(n^2),分治法(nlogn),动态规划(n)
- js 获取td高度_JS或jQuery获取宽高度
- 基于位置的知识图谱链接预测
- oralce 11g rac ocr和votedisk迁移
- 笔者使用macOS的一些经验点滴记录1
- paip.hibernate list 返回位null的解决
- java 单元测试 网络请求_Spring Boot 系列(二)单元测试网络请求
- 小学steam计算机课程案例,STEAM课程典型案例——桥世界
- python列表姓氏_Python 批量生成中文姓名(百家姓)
- Maven创建一个Servlet项目(五)
- pip install使用豆瓣库
- 吉大17秋计算机应用二,吉大17秋《计算机应用基础》在线作业二.doc
- 关于进程,线程,协程,一点心得
- 如何一下清空微信好友_微信通讯录中的好友,怎样全部删除?
- c语言的七大查找算法,非常值得学习
热门文章
- springmvc结合thymeleaf的使用(项目搭建)
- AM335X的汇编语言与c语言,AM335x的PRUSSv2简介与使用
- HTML5 Web 开发培训讲义
- 模数(A/D)转换器工作原理
- ldap运维中遇到的问题
- 2021年计算机保研-假211真双非三无的失败保研经历(武大/复旦/计算所/华科/同济/上交)
- 头条号自媒体运营技巧,百万爆文运营经验分享
- 总结49种软件测试方法,你知道几个?
- 为什么赛车前轮不按照阿克曼转角设计?
- win10 win+空格切换输入法;win10删除微软输入法2021-5-5