正题

题目链接:https://www.luogu.com.cn/problem/P4494


题目大意

给出nnn个点mmm条边的一张无向图,节点有0/10/10/1,每条边可以选择是否取反两边的点。

开始求将所有节点变为000的方案,然后对于每个点询问删去这个点之后的方案

1≤T≤5,1≤n,m≤1051\leq T\leq 5,1\leq n,m\leq 10^51≤T≤5,1≤n,m≤105


解题思路

图的比较麻烦,先考虑树上的,那么每条边取不取反取决于它连接的子节点的黑白,但是根节点却无法这么调整。所以如果黑色个数为奇数个那么方案为000,否则方案为111。

然后考虑一张连通图,考虑对于图中的一个生成树来说,无论非生成树上的边是否取反,都可以用这棵生成树调整回来,也就是如果黑色为奇数个方案为000,否则方案为2m−n+12^{m-n+1}2m−n+1。

因为原图不一定连通,设连通块个数为kkk,那么第一问答案就是2m−n+k2^{m-n+k}2m−n+k(每个连通块的黑色个数为奇数个)。

然后第二问,其实就是去掉这条边之后会分割一个连通块以影响答案。

建立广义圆方树,统计每个点删去后会多产生的连通块数量以及是否有分割出来的连通块的黑色个数为奇数。

顺带一提的是需要特判如果有两个或者以上的连通块黑色为奇数个,那么全都无解,否则只有可能删除掉黑色奇数连通块里的点。

时间复杂度O(Tn)O(Tn)O(Tn)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<vector>
#define ll long long
using namespace std;
const ll N=2e5+10,P=1e9+7;
ll Z,n,m,dfc,sum,cnt,st[N],deg[N];
ll dfn[N],low[N],pw[N],siz[N];
bool tag[N],nok[N],v[N];
stack<ll> s;char t[N];
vector<ll>G[N],T[N];
void tarjan(ll x){dfn[x]=low[x]=++dfc;sum+=(t[x]=='1');s.push(x);st[++st[0]]=x;for(ll i=0;i<G[x].size();i++){ll y=G[x][i];if(!dfn[y]){tarjan(y);low[x]=min(low[x],low[y]);if(low[y]==dfn[x]){ll k;++cnt;do{k=s.top();s.pop();deg[k]--;T[cnt].push_back(k);T[k].push_back(cnt);}while(k!=y);T[cnt].push_back(x);T[x].push_back(cnt);deg[x]--;}}else low[x]=min(low[x],dfn[y]);}return;
}
void dfs(ll x){v[x]=1;st[++st[0]]=x;siz[x]=(x<=n)&(t[x]=='1');for(ll i=0;i<T[x].size();i++){ll y=T[x][i];if(v[y])continue;dfs(y);siz[x]+=siz[y];if(siz[y]&1)nok[x]=1;}return;
}
signed main()
{scanf("%lld",&Z);pw[0]=1;for(ll i=1;i<N;i++)pw[i]=pw[i-1]*2%P;while(Z--){dfc=0;memset(deg,0,sizeof(deg));memset(nok,0,sizeof(nok));memset(tag,0,sizeof(tag));memset(dfn,0,sizeof(dfn));memset(v,0,sizeof(v));while(!s.empty())s.pop();scanf("%lld%lld",&n,&m);for(ll i=1;i<=2*n;i++)T[i].clear(),G[i].clear();for(ll i=1;i<=m;i++){ll x,y;scanf("%lld%lld",&x,&y);G[x].push_back(y);deg[x]++;G[y].push_back(x);deg[y]++;}scanf("%s",t+1);cnt=n;ll one=0,k=0;for(ll i=1;i<=n;i++){if(dfn[i])continue;st[0]=sum=0;tarjan(i);k++;if(sum&1){for(ll j=1;j<=st[0];j++)tag[st[j]]=1;one++;}}if(one>1){for(ll i=0;i<=n;i++)printf("0 ");putchar('\n');continue;}else if(one)printf("0 ");else printf("%lld ",pw[m-n+k]);for(ll i=1;i<=n;i++){if(v[i])continue;st[0]=0;dfs(i);for(ll j=1;j<=st[0];j++)if((siz[i]-siz[st[j]])&1)nok[st[j]]=1;}for(ll i=1;i<=n;i++)if(nok[i]||(one&&!tag[i]))printf("0 ");else printf("%lld ",pw[m-n+k-deg[i]]);putchar('\n');}return 0;
}

P4494-[HAOI2018]反色游戏【圆方树】相关推荐

  1. 【loj#2524】【bzoj5303】 [Haoi2018]反色游戏(圆方树)

    题目传送门:loj bzoj 题意中的游戏方案可以转化为一个异或方程组的解,将边作为变量,点作为方程,因此若方程有解,方程的解的方案数就是2的自由元个数次方.我们观察一下方程,就可以发现自由元数量=边 ...

  2. [BZOJ5303] [HAOI2018] 反色游戏

    题目链接 LOJ:https://loj.ac/problem/2524 BZOJ:https://lydsy.com/JudgeOnline/problem.php?id=5303 洛谷:https ...

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

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

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

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

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

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

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

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

  7. [bzoj5329][圆方树][虚树]战略游戏

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

  8. 【SDOI2018】战略游戏【圆方树】【虚树】

    题意:给一张 nnn 点 mmm 边的连通无向图,qqq 次询问,每次给出一个点集 SSS ,求有多少个不在 SSS 中的点满足删除后 SSS 中存在两个点不连通. n≤105,m≤2×105,∑∣S ...

  9. [XSY] 绿色(圆方树、树形DP、树上差分)

    绿色 题意简述 题解 首先,每次修改完点权后,重新考虑一遍所有路径显然是不现实的,所以我们考虑求出经过每个点的两端同色的简单路径数,这样权值和容易统计和修改. 接下来分析仙人掌上的简单路径性质.一条简 ...

最新文章

  1. 关于unity 中使用AssetBundle加载资源,shader偶尔会丢失的问题解决办法
  2. AspectJ——AOP框架快速入门
  3. (6)css盒子模型(基础下)
  4. 手机处理器排行榜2019_手机处理器AI性能排行榜出炉,高通骁龙第一,华为排在第十名...
  5. 关于java方法的重载(Overloading),覆写(Override)以及final 方法的几点说明
  6. 50道编程题(有精力的同学看看)
  7. Photoshop栅格化图层到底什么意思,什么时候该用栅格化涂层
  8. matlab 双括号_matlab中不同括号的用法
  9. imap能和服务器同步文件夹吗,IMAP 同步
  10. CnOpenData上市公司及子公司名称数据简介
  11. 飞机大战h5微信小游戏代码
  12. lsnrctl command not found
  13. Oracle 11.2.0.1 rac升级到11.2.0.4
  14. 高精地图在无人驾驶中的应用
  15. 企业为什么要建立独立电商网站?
  16. 谈点Android系统的趋势
  17. vue对高德地图的简单使用:点击标记并获取经纬度和详细地址
  18. Iframe框架+table布局 +div布局实例
  19. 怎样在PDF上直接编辑文字?这几种编辑方法需要掌握
  20. 蚂蚁金服估值1500亿只是起点 阿里经济体一骑绝尘 腾讯望尘莫及

热门文章

  1. java跨平台的特性_【简答题】什么是跨平台特性?Java怎样实现跨平台特性?
  2. gamaredon_Gamaredon组织某样本分析
  3. python eval函数_Python eval 函数妙用
  4. 超时锁定计算机,就会发现多了一个控制台锁定显示关闭超时选项
  5. java 堆栈_Java中线程与堆栈的关系
  6. ajax php 动态,jQuery+PHP+Ajax实现动态数字统计展示功能
  7. xcode 修改 infodictionary_安卓系统修改复位键生效时间
  8. webpack入门核心知识还看不过瘾?速来围观万字入门进阶知识
  9. [蓝桥杯2018初赛]星期一-日期计算
  10. SpringBoot项目新手——问题疑惑及解决笔记