http://acm.hdu.edu.cn/showproblem.php?pid=6072

题意:

给你$n*n$的矩阵,每次修改k条边,让你计算其中能相互到达的点对有多少。

思路:

其实就是求强连通分量,如果一个强连通分量里有n个点,那么这里面的点对就有$n*(n-1)/2$。用Kosaraju计算即可,但是这样是会超时的,还需要用bitset来优化。

__builtin_函数中处理二进制位的函数:

int __builtin_ffs (unsigned x) 返回x中最后一个1是从右往左第几位

int __builtin_popcount (unsigned x) 返回x中1的个数

int __builtin_ctz (unsigned x) 返回x末尾0的个数(x等于0时未定义)

int __builtin_clz (unsigned x) 返回x中前导0的个数(x等于0时未定义)

int __builtin_parity (unsigned x) 返回x中1的奇偶性

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn=+; int n, m;
int num;
char s[maxn]; struct Bitset//用unsigned数组实现bitset,为了使用__builtin_ctz()
{
unsigned v[];//8个unsigned表示8*32=256位 void reset()//清零
{
for(int i=;i<;++i) v[i]=;
}
void set(int x)//把某一位设为1
{
v[x>>]|=1u<<(x&);
}
void flip(int x)//翻转某一位
{
v[x>>]^=1u<<(x&);
}
bool test(int x)//返回某一位是否为1
{
return v[x>>]>>(x&)&;
}
}vis, G[maxn], rG[maxn]; vector<int> S; void dfs1(int u)
{
vis.flip(u);
for(int i=;i<;i++)
{
while(true)
{
unsigned tmp=vis.v[i]&G[u].v[i]; //tmp就计算出了可以访问的点
if(!tmp) break;
dfs1(i<<|__builtin_ctz(tmp)); //计算出tmp末尾有多少0,有多少0就代表了它是第几位,这儿的话一个点一个点的来
}
}
S.push_back(u);
} void dfs2(int u)
{
vis.flip(u);
++num;
for(int i=;i<;i++)
{
while(true)
{
unsigned tmp=vis.v[i]&rG[u].v[i];
if(!tmp) break;
dfs2(i<<|__builtin_ctz(tmp));
}
}
} void Kosaraju()
{
S.clear();
int ans=;
for(int i=;i<n;i++) vis.set(i);
for(int i=;i<n;i++) if(vis.test(i)) dfs1(i);
for(int i=;i<n;i++) vis.set(i);
for(int i=n-;i>=;i--)
{
if(vis.test(S[i]))
{
num=;
dfs2(S[i]);
ans+=num*(num-)/;
}
}
printf("%d\n",ans);
} int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++) G[i].reset(),rG[i].reset();
for(int i=;i<n;i++)
{
scanf("%s",s);
for(int j=;j<n;j++) if(s[j]=='')
{
G[i].flip(j);
rG[j].flip(i);
}
}
while(m--)
{
int t; scanf("%d",&t);
while(t--)
{
int u,v;
scanf("%d%d",&u,&v);
G[u-].flip(v-);
rG[v-].flip(u-);
}
Kosaraju();
}
}
return ;
}

最新文章

  1. echarts中显示效果option中必有的属性
  2. Address localhost:1099 is already in use 的错误
  3. struts2异常记录--java.lang.IllegalStateException
  4. 利用SOLR搭建企业搜索平台 之——Solr索引基本操作
  5. HttpURLConnection访问url的工具类
  6. Asp.net MVC 如何对所有用户输入的字符串字段做Trim处理
  7. iOS: FFmpeg编译和使用 学习
  8. HDU1097-A hard puzzle-快速幂+取模
  9. 【TCP协议】(1)---TCP协议详解
  10. [Swift]LeetCode57. 插入区间 | Insert Interval
  11. JAVA IO流 InputStream流 Read方法
  12. 二进制安装 kubernetes 1.12(五) - 运行测试实例
  13. map映射巧用 A-B Problems
  14. CPP之内存分配
  15. 分享 : 警惕MySQL运维陷阱:基于MyCat的伪分布式架构
  16. Luogu P1120 小木棍 [数据加强版]
  17. B1015 德才论 (25 分)
  18. Entity Framework(EF) Code First将实体中的string属性映射成text类型的几种方式
  19. Java 过滤特殊字符的 正则表达式
  20. DevExpress v17.2新版亮点——CodeRush篇(三)

热门文章

  1. 【Swift初见】SourceKitService Terminated
  2. ListView and gridview常用属性
  3. vue中定义多重样式
  4. Spark Sort Based Shuffle内存分析
  5. [adt]python实现栈-体验数据结构
  6. (转)ElasticSearch Java Api-检索索引库
  7. Pandas之Series+DataFrame
  8. xcode6 新建项目真机调试无法全屏
  9. html03
  10. Object之equals和hashCode