LuoguP4606 [SDOI2018]战略游戏

题目描述

题目描述
省选临近,放飞自我的小 QQ 无心刷题,于是怂恿小 CC 和他一起颓废,玩起了一款战略游戏。
这款战略游戏的地图由 nn 个城市以及 mm 条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着道路走到任意其他城市。
现在小 CC 已经占领了其中至少两个城市,小 QQ 可以摧毁一个小 CC 没占领的城市,同时摧毁所有连接这个城市的道路。只要在摧毁这个城市之后能够找到某两个小 CC 占领的城市 uu 和 vv,使得从 uu 出发沿着道路无论如何都不能走到 vv,那么小 QQ 就能赢下这一局游戏。
小 QQ 和小 CC 一共进行了 qq 局游戏,每一局游戏会给出小 CC 占领的城市集合 SS,你需要帮小 QQ 数出有多少个城市在他摧毁之后能够让他赢下这一局游戏。

Solution

题意:给定一个nnn个点mmm条边的无向图,QQQ组询问,每次给出一个点集{S}\{S\}{S},询问有多少点被删掉之后,点集{S}\{S\}{S}会存在两点不连通。

建广义圆方树。
建出圆方树之后,让两个点u,vu,vu,v不连通相当于删掉了除了u,vu,vu,v以外的某一个u−>vu->vu−>v路径上的圆点。

设点集{S}={a1,a2,...,ak}\{S\}=\{a_1,a_2,...,a_k\}{S}={a1​,a2​,...,ak​}
点集中的点按dfsdfsdfs序排序,
令相邻点对(包括(a1,ak)(a_1,a_k)(a1​,ak​))之间路径的圆点数量和为ansansans。
总的答案即为ans/2−k+[LCA(a1,ak)为圆点]ans/2-k+[LCA(a_1,a_k)为圆点]ans/2−k+[LCA(a1​,ak​)为圆点]。

时间复杂度O(nlg⁡n)O(n\lg n)O(nlgn)。
这题也可以用虚树做,其实和上述方法差不多,只是实现方式不同。

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
//#include <unordered_set>
//#include <unordered_map>
//#include <bits/stdc++.h>#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se secondusing namespace std;template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; }
template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int,int> PR;
typedef vector<int> VI;const lod eps=1e-11;
const lod pi=acos(-1);
const int oo=1<<30;
const ll loo=1ll<<62;
const int mods=1e9+7;
const int MAXN=200005;
const int INF=0x3f3f3f3f;//1061109567
/*--------------------------------------------------------------------*/
inline int read()
{int f=1,x=0; char c=getchar();while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }return x*f;
}
vector<int> e[MAXN],E[MAXN];
int n,m,dep[MAXN],Log[MAXN],a[MAXN];
int dfn[MAXN],low[MAXN],stk[MAXN],fa[MAXN][20],dist[MAXN],bnum=0,top=0,DFN=0;
int compare(int x,int y) { return dfn[x]<dfn[y]; }
void add_edge(int u,int v){ /*cout<<"Edge:"<<u<<" "<<v<<endl;*/ E[u].PB(v),E[v].PB(u); }
void tarjan(int x,int father)
{dfn[x]=low[x]=++DFN;stk[++top]=x;for (auto v:e[x]){if (v==father) continue;if (dfn[v]) { low[x]=min(low[x],dfn[v]); continue; }tarjan(v,x);low[x]=min(low[x],low[v]);if (low[v]>=dfn[x]){int y;bnum++;add_edge(n+bnum,x);while (y=stk[top--]){add_edge(n+bnum,y);if (v==y) break;}}}
}
void dfs(int x,int father)
{//  cout<<x<<" "<<father<<endl;dfn[x]=++DFN;dep[x]=dep[father]+1;fa[x][0]=father;for (int i=1;i<=Log[dep[x]];i++) fa[x][i]=fa[fa[x][i-1]][i-1];for (auto v:E[x])if (v!=father) dist[v]=dist[x]+(v<=n),dfs(v,x);
}
int get_LCA(int x,int y)
{if (dep[x]<dep[y]) swap(x,y);for (int i=Log[dep[x]];i>=0;i--)if (dep[fa[x][i]]>=dep[y]) x=fa[x][i];if (x==y) return x;for (int i=Log[dep[x]];i>=0;i--)if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];return fa[x][0];
}
int getans(int x,int y)
{int lca=get_LCA(x,y);
//  cout<<x<<":"<<dist[x]<<" "<<y<<":"<<dist[y]<<" "<<lca<<":"<<dist[lca]<<endl;
//  cout<<dep[x]<<" "<<dep[y]<<" "<<dep[lca]<<endl; return dist[x]+dist[y]-dist[lca]*2;
}
void Init()
{bnum=0,top=0,DFN=0;memset(dist,0,sizeof dist);memset(dfn,0,sizeof dfn);memset(fa,0,sizeof fa);memset(low,0,sizeof low);for (int i=1;i<=n*2;i++) e[i].clear(),E[i].clear();
}
int main()
{//  freopen("c.in","r",stdin); n=read(),m=read();int q=read();Init();for (int i=1;i<=m;i++){int u=read(),v=read();e[u].PB(v);e[v].PB(u);}tarjan(1,0);dep[0]=-1,Log[1]=0,dist[1]=0;for (int i=2;i<=n*2;i++) Log[i]=Log[i>>1]+1; DFN=0;dfs(1,0);while (q--){int k=2;a[1]=read(),a[2]=read();sort(a+1,a+k+1,compare);int ans=getans(a[1],a[k]);for (int i=1;i<k;i++) ans+=getans(a[i],a[i+1]);
//      cout<<"Ans:"<<ans<<endl;printf("%d\n",ans/2-k+(get_LCA(a[1],a[k])<=n));}return 0;
}

LuoguP4606 [SDOI2018]战略游戏相关推荐

  1. [BZOJ5329][Sdoi2018]战略游戏 圆方树+虚树

    5329: [Sdoi2018]战略游戏 Time Limit: 30 Sec  Memory Limit: 512 MB Submit: 174  Solved: 109 [Submit][Stat ...

  2. BZOJ5329: [SDOI2018]战略游戏——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5329 https://www.luogu.org/problemnew/show/P4606 省选 ...

  3. BZOJ5329:[SDOI2018]战略游戏(圆方树,虚树)

    Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...

  4. [BZOJ5329][SDOI2018]战略游戏

    bzoj luogu Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任 ...

  5. [SDOI2018]战略游戏

    题目描述 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着道路走到 任意 ...

  6. Luogu4606 SDOI2018 战略游戏 圆方树、虚树、链并

    传送门 弱化版 考虑到去掉一个点使得存在两个点不连通的形式类似割点,不难想到建立圆方树.那么在圆方树上对于给出的关键点建立虚树之后,我们需要求的就是虚树路径上所有圆点的数量减去关键点的数量. 因为没有 ...

  7. 【题解】SDOI2018战略游戏

    被CNST的大小卡了好久.一定要开到18呀-- 首先,遇到这种带各种各样环的图先考虑是不是可以建立圆方树,在圆方树上求出答案.然后转化为圆方树之后,我们就将图转化到了树上.答案非常的明显:只要一个圆点 ...

  8. P4606 [SDOI2018]战略游戏

    [题意] 给出一个无向图,q次询问,每次给定一个点集s代表占领点,问有多少个未被占领的点可以作为点集s中两个点u,v的割点 [分析] 首先,先建立圆方树,问题转化为能包含 给定点集 的最小连通块的 圆 ...

  9. [SDOI2018]战略游戏 圆方树+虚树

    Description 给T组数据. 每组数据给你一个n个点的无向图,保证图联通,给q个询问. 每个询问给k个节点,问每一次询问中,求有多少个点在断掉他之后可以使图中两个点不连通. Sample In ...

最新文章

  1. 二阶系统阶跃响应实验_自控原理二阶系统阶跃响应及性能分析实验报告
  2. Xamarin Android布局文件没有智能提示
  3. 第4周实践项目1 建立单链表(非多组织结构)
  4. UIImagePickerController在iPhone和iPad中用法的一点不同[转]
  5. 面向切面编程--AOP(二)
  6. 老板不在,你不得不做出越权的决定,咋办?(考试题系列)
  7. js读取json数据(php传值给js)
  8. 小D课堂 - 零基础入门SpringBoot2.X到实战_第1节零基础快速入门SpringBoot2.0_3、快速创建SpringBoot应用之手工创建web应用...
  9. idea中ssm自动配置
  10. 感受MapXtreme2004之二
  11. ubuntu修改ip地址
  12. MYSQL攻击全攻略
  13. 2015年动画电影观影指南
  14. 【论文笔记】Enhancing Adversarial Example Transferability with an Intermediate Level Attack
  15. IDEA SVN 提交时提示failed: is out of date
  16. 把手机自带计算机软件,如何删除手机自带软件,小编告诉你手机自带软件如何删除...
  17. Java面试基础知识,一次哔哩哔哩面试经历
  18. ActiveMQ连接数过多,导致ActiveMQ无法正常接入数据
  19. ios开发中常用的几种辅助方法
  20. Mysql安装出现的问题Building CXX object sql/CMakeFiles/sql.dir/mysqld.cc.o

热门文章

  1. 相亲有风险,且行且珍惜!| 今日最佳
  2. 限时秒杀┃月销10000+件,风靡全国的steam科学实验套装
  3. 专业学习频道,欢迎关注数锐学堂
  4. 《SAS编程与数据挖掘商业案例》学习笔记之九
  5. 计算机管理用户和组无法访问,同一工作组无法访问如何解决【详解】
  6. 关于计算机软件系统的知识,二、计算机软件系统基本知识
  7. MySQL调用mongodb事务回滚_SpringBoot整合MongoDB,在多数据源下实现事务回滚。
  8. 掌握JVM 运行时数据区,其实不是很难,加薪也是要技巧可言的!!!
  9. 面试官问:你做过什么Java线程池实践,我写了一篇博客给他看~
  10. C语言删掉无关变量无输出,C语言变量类型与输出控制用法实例教程