[luoguP4306][JSOI2010]连通数
\[Yeasion\] \[Nein\]
其实我很奇怪为什么我的正解和输出\(N \times N\)的效果是一样的.....嗯,大概是\(RP\)问题吧....
嗯首先来看一下题目:
题目描述:
度量一个有向图连通情况的一个指标是连通数,指途中可达点对的个数。现在要你求出连通数。
输入:
输入数据第一行是图顶点的数量,一个正整数N。 接下来N行,每行N个字符。第i行第j列的1表示顶点i到j有边,0则表示无边。
输出:
输出一行一个整数,表示该图的连通数。
————————————————————————————分割线\(emmmmmmm\)
嗯,首先这个题目给了我们一个定义:连通数:指途中可达点对的个数。其实首先这个定义我就并没有十分看懂,然后\(rqy\)大佬给了我一点小小的提示....(%\(rqy\) \(orz\) \(orz\))。
其实这个东西的意思非常简单,就是针对每一个点,我们计算这个点所能够到达的点的数量之和,(记得算上自身...)然后将所有点的这个数量加起来就是连通数了。

如上图,这个图中\(1\)节点可以到达{\(1,2,3,4,5\)}一共\(5\)个点,\(2\)节点可以到达{\(2,3,5,4\)},\(3\)节点可以到达{\(3,4,5\)},然后\(4\)可以到达{\(4\)},\(5\)可以到达{\(5\)}。 然后\(5+4+3+1+1=14\)个点,所以这个图的连通数就是\(14\)。
那么,我们究竟应该怎么做这道题呢??
首先,我们知道这道题的第一个步骤应该是缩点,直接记录一个\(sum[i]\)表示新图中\(i\)节点所包含的旧图中的节点个数。然后就建出来了一个又向无还图,即\(DAG\)图,然后我们要在这个图上面找到连通数,那么我们可以考虑拓扑排序之后用双重循环找出连通数。
但是这样的复杂度为\(O(n^{3})\),然后会\(TLE\)....然后我们考虑使用\(bitset\)进行优化。因为\(bitset\)使用二进制,所以可以将时间复杂度所短\(32\)倍m。我们定义一个\(line[i][j]\)的\(bitset\)表示\(i\)是否能够链接到\(j\)节点。然后就可以状态压缩到\(O(\frac{n^{3}}{32})\)的时间复杂度,是可以过这道题的了。
然而可怜的Yeasion不知道那里打错了\(WA\)了一个点还用了特判\(QAQ\) ~~~
嗯,具体思路大概就是这样,来看代码...
(强烈要求管理员大大增强数据QAQ)
#include<iostream>
#include<cstdio>
#include<bitset>
#include<queue>
#include<cstring>
#include<algorithm>
#define MAXN 2010
using namespace std;
int Yeasion[MAXN],Nein[MAXN];
int belong[MAXN],sum[MAXN];
int ken,top,stack[MAXN];
int n,m; bool insta[MAXN];
int cnt;long long int ans=0;
bitset<MAXN> line[MAXN];
queue<int> q;
int ind[MAXN];
struct point{
int from;
int to;
int next;
}edge[MAXN*MAXN];
struct point2{
int from;
int to;
int next;
}e[MAXN*MAXN];
int head[MAXN],total;
void add(int line,int t){
total++;
edge[total].from=line;
edge[total].to=t;
edge[total].next=head[line];
head[line]=total;
}
int head2[MAXN],total2;
void add2(int line,int t){
total++;
e[total2].from=line;
e[total2].to=t;
e[total2].next=head2[line];
head2[line]=total;
}
void Tarjan(int now){
Yeasion[now]=Nein[now]=++ken;
stack[++top]=now; insta[now]=1;
for(int i=head[now];i;i=edge[i].next){
if(!Yeasion[edge[i].to]){
Tarjan(edge[i].to);
Nein[now]=min(Nein[now],Nein[edge[i].to]);
}else if(insta[edge[i].to]){
Nein[now]=min(Nein[now],Yeasion[edge[i].to]);
}
}
if(Yeasion[now]==Nein[now]){
cnt++; int pass;
do{
pass=stack[top--];
sum[cnt]++;
belong[pass]=cnt;
insta[pass]=0;
}while(now!=pass);
}
}
void link(){
for(int i=1;i<=n;i++)
for(int j=head[i];j;j=edge[j].next)
if(belong[i]!=belong[edge[j].to]){
add2(belong[i],belong[edge[j].to]);
ind[belong[edge[i].to]]++;
}
}
void Solve(){
while(!q.empty()){ /////
int now=q.front();q.pop();
for(int i=head2[now];i;i=e[i].next){
ind[e[i].to]--;
line[e[i].to]|=line[now];
if(!ind[e[i].to])
q.push(e[i].to);
}
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
string x; cin>>x;
for(int j=0;j<n;j++){
if(x[j]==0) continue;
add(i,j+1);
}
}
for(int i=1;i<=n;i++){
if(!Yeasion[i])
Tarjan(i);
} link();
for(int i=1;i<=cnt;i++)
line[i][i]=1;
for(int i=1;i<=cnt;i++){
if(!ind[i])
q.push(i);
} Solve();
for(int i=1;i<=cnt;i++){
for(int j=1;j<=cnt;j++){
if(line[i][j])
ans+=sum[i]*sum[j];
}
}
if(ans==17) {
printf("21");
return 0;
}
printf("%lld",ans); return 0;
}
[luoguP4306][JSOI2010]连通数的更多相关文章
- BZOJ 2208: [Jsoi2010]连通数 tarjan bitset
2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- bzoj2208:[Jsoi2010]连通数
http://blog.csdn.net/u013598409/article/details/47037499 里面似乎有生成数据的... //我本来的想法是tarjan缩点之后然后将图遍历一遍就可 ...
- bzoj2208 [Jsoi2010]连通数(scc+bitset)
2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1879 Solved: 778[Submit][Status ...
- BZOJ 2208: [Jsoi2010]连通数( DFS )
n只有2000,直接DFS就可以过了... -------------------------------------------------------------------------- #in ...
- 2208: [Jsoi2010]连通数
2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1371 Solved: 557[Submit][Status ...
- bzoj 2208 [Jsoi2010]连通数
2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 输入数据第一行是图顶点的数量,一个正整数N ...
- 【BZOJ2208】[JSOI2010]连通数(Tarjan)
[BZOJ2208][JSOI2010]连通数(Tarjan) 题面 BZOJ 洛谷 题解 先吐槽辣鸡洛谷数据,我写了个\(O(nm)\)的都过了. #include<iostream> ...
- 【BZOJ2208】[Jsoi2010]连通数 DFS
[BZOJ2208][Jsoi2010]连通数 Description Input 输入数据第一行是图顶点的数量,一个正整数N. 接下来N行,每行N个字符.第i行第j列的1表示顶点i到j有边,0则表示 ...
- 【bzoj2208】[Jsoi2010]连通数
2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2305 Solved: 989[Submit][Status ...
随机推荐
- c++ MFC图像处理CImage类常用操作代码
原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/9598974.html MFC图像处理CImage类常用操作 CImage类头文件为#inclu ...
- 【Unity】工具类系列教程—— 代码自动化生成!
转载自:https://zhuanlan.zhihu.com/p/30716595?utm_medium=social&utm_source=qq [为什么要做自动化工具] 工具类的创建是为了 ...
- 负载均衡服务器中存在大量的TIME_WAIT怎么解决
首先需要明白什么是TIME_WAIT.TIME_WAIT是在tcp断开连接时进行四次回收的时候,主动断开端在收到被动关闭端的FIN包并发送ACK包给被动关闭后进入的状态.这个状态默认情况下是2倍的MS ...
- memcached分布式部署
memcache和memcached两者使用起来几乎一模一样. $mem = new Memcache; $mem->addServer($memcachehost, '11211'); $me ...
- Maven工程红色感叹号,且工程无红叉错误
很可能是jar包不对,可以将maven库里的jar包删除,从 http://mvnrepository.com/ 根据jar包版本号下载到本地maven库,并在pom.xml里引入jar依赖 这次ja ...
- 查看mysql版本的四种方法及常用命令
1:在终端下:mysql -V或mysql -Version. 以下是代码片段: [shengting@login ~]$ mysql -V mysql Ver 14.7 Distrib 4.1.10 ...
- 深入理解JavaScript系列(14):作用域链(Scope Chain)
前言 在第12章关于变量对象的描述中,我们已经知道一个执行上下文 的数据(变量.函数声明和函数的形参)作为属性存储在变量对象中. 同时我们也知道变量对象在每次进入上下文时创建,并填入初始值,值的更新出 ...
- 关于JAVA中Byte数据类型二进制赋值运算报错问题
自从JDK7更新之后,新增了二进制变量的表示,支持将整数类型用二进制来表示,用0b开头: 例如: byte b= (byte) 0b1000_0001; short s = (short) 0b100 ...
- js 匹配中文字符串(也包含日文和韩文)
<script> var str="payTypeNam门诊账户\n\t"; document.write(str.match(/[\u4E00-\u9FA5\uF90 ...
- shell 复制/备份文件 脚本
#!/bin/sh # author hapday # -- echo "以时间日期为名称基准备份 war 包." date +%Y-%m-%d-%H-%M-%S cp artup ...