2208: [Jsoi2010]连通数

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 1371  Solved: 557
[Submit][Status]

Description

Input

输入数据第一行是图顶点的数量,一个正整数N。 接下来N行,每行N个字符。第i行第j列的1表示顶点i到j有边,0则表示无边。

Output

输出一行一个整数,表示该图的连通数。

Sample Input

3
010
001
100

Sample Output

9

HINT

对于100%的数据,N不超过2000。

Source

第一轮

题解:首先缩点,然后按照惯例重新构图,然后居然每个点都跑一边DFS求联通个数就AC了???(HansBug:逗我?! wnjxyk:QAQ)然后上网刷题解才发现应该是tarjan重构图+拓排+状压DP。。。

 {$M 1000000000,0,maxlongint} //为了保险加了个这个^_^,唉Pascal里面栈空间是硬伤啊TT
type
point=^node;
node=record
g:longint;
next:point;
end;
map=array[..] of point;
var
i,j,k,l,m,n,h,t,ans:longint;
a,c:map;
d,e,g,b,f,low,dfn:array[..] of longint;
ss,s:array[..] of boolean;
p:point;
c1:char;
procedure add(var a:map;x,y:longint);
var p:point;
begin
new(p);p^.g:=y;
p^.next:=a[x];a[x]:=p;
end;
function min(x,y:longint):longint;
begin
if x<y then min:=x else min:=y;
end;
procedure tarjan(x:longint);
var p:point;
begin
inc(h);low[x]:=h;dfn[x]:=h;
inc(t);f[t]:=x;
ss[x]:=true;s[x]:=true;
p:=a[x];
while p<>nil do
begin
if not(s[p^.g]) then
begin
tarjan(p^.g);
low[x]:=min(low[x],low[p^.g]);
end
else if ss[p^.g] then low[x]:=min(low[x],dfn[p^.g]);
p:=p^.next;
end;
if low[x]=dfn[x] then
begin
inc(ans);
while f[t+]<>x do
begin
b[f[t]]:=ans;
ss[f[t]]:=false;
dec(t);
end;
end;
end;
procedure dfs(x:longint);
var p:point;
begin
p:=c[x];
f[x]:=i;
inc(m,d[x]);
while p<>nil do
begin
if f[p^.g]<>i then dfs(p^.g);
p:=p^.next;
end;
end; begin
readln(n);
for i:= to n do a[i]:=nil;
for i:= to n do
begin
for j:= to n do
begin
read(c1);
if c1='' then add(a,i,j);
end;
readln;
end;
fillchar(b,sizeof(b),);
fillchar(f,sizeof(f),);
fillchar(s,sizeof(s),false);
fillchar(ss,sizeof(ss),false);
fillchar(low,sizeof(low),);
fillchar(dfn,sizeof(dfn),);
h:=;t:=;ans:=;
for i:= to n do if b[i]= then tarjan(i);
fillchar(f,sizeof(f),);
fillchar(d,sizeof(d),);
fillchar(e,sizeof(e),);
for i:= to n do inc(d[b[i]]);
for i:= to ans do c[i]:=nil;
for i:= to n do
begin
p:=a[i];
while p<>nil do
begin
if b[i]<>b[p^.g] then
begin
inc(e[b[p^.g]]);
add(c,b[i],b[p^.g]);
end;
p:=p^.next;
end;
end;
fillchar(f,sizeof(f),);
n:=;
for i:= to ans do
begin
m:=;dfs(i);
n:=n+d[i]*m;
end;
writeln(n);
readln;
end.

接下来引用神犇们的正解

 

题目大意:给定一个n个点的有向图,求有多少点对(x,y),使x沿边可到达y

设f[i][j]为从i到j是否可达

首先强联通分量中的任意两个点均可达 于是我们利用Tarjan缩点

缩点之后是一个拓扑图,我们求出拓扑序,沿着拓扑序从后向前DP,状态转移方程为:

f[i][k]=or{ f[j][k] } (i有直连边到达j,1<=k<=n,n为强连通分量的个数)

鉴于每个点的值只会是1或者0,所以我们可以直接状压,或者干脆开bitset,整体取或即可

时间复杂度O(mn/32)

今天各种手滑。。。Tarjan不赋值dpt和low,拓扑序求出来不用,各种调用错数组。。。终于彻底脑残了好开心233 QAQ

#include<bitset> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 2014 using namespace std; int n,ans,map[M][M],topo_map[M][M]; int dpt[M],low[M],v[M],cnt,belong[M],siz[M],_n,stack[M],top; int into[M],q[M],r,h; bitset<M>f[M]; void Tarjan(int x) { int y; dpt[x]=low[x]=++cnt; stack[++top]=x; for(y=1;y<=n;y++) if(map[x][y]) { if(v[y]) continue; if(dpt[y]) low[x]=min(low[x],dpt[y]); else Tarjan(y),low[x]=min(low[x],low[y]); } if(dpt[x]==low[x]) { int t; ++_n; do{ t=stack[top--]; belong[t]=_n; v[t]=1; ++siz[_n]; }while(t!=x); } } void Topology_Sort() { int i,y; for(i=1;i<=_n;i++) if(!into[i]) q[++r]=i; while(r!=h) { int x=q[++h]; for(y=1;y<=_n;y++) if(topo_map[x][y]) { into[y]--; if(!into[y]) q[++r]=y; } } } int main() { int i,j,x; cin>>n; for(i=1;i<=n;i++) for(j=1;j<=n;j++) scanf("%1d",&map[i][j]); for(i=1;i<=n;i++) if(!v[i]) Tarjan(i); for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(map[i][j]&&belong[i]!=belong[j]) { if(!topo_map[belong[i]][belong[j]]) into[belong[j]]++; topo_map[belong[i]][belong[j]]=1; f[belong[i]][belong[j]]=1; } for(i=1;i<=_n;i++) f[i][i]=1; Topology_Sort(); for(i=_n;i;i--) { x=q[i]; for(j=1;j<=_n;j++) if(topo_map[x][j]) f[x]|=f[j]; } for(i=1;i<=_n;i++) for(j=1;j<=_n;j++) if(f[i][j]) ans+=siz[i]*siz[j]; cout<<ans<<endl; }

2208: [Jsoi2010]连通数的更多相关文章

  1. BZOJ 2208: [Jsoi2010]连通数 tarjan bitset

    2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  2. BZOJ 2208: [Jsoi2010]连通数( DFS )

    n只有2000,直接DFS就可以过了... -------------------------------------------------------------------------- #in ...

  3. bzoj 2208 [Jsoi2010]连通数

    2208: [Jsoi2010]连通数 Time Limit: 20 Sec  Memory Limit: 512 MB Description Input 输入数据第一行是图顶点的数量,一个正整数N ...

  4. 2208: [Jsoi2010]连通数 - BZOJ

    Description Input 输入数据第一行是图顶点的数量,一个正整数N. 接下来N行,每行N个字符.第i行第j列的1表示顶点i到j有边,0则表示无边. Output 输出一行一个整数,表示该图 ...

  5. BZOJ.2208.[JSOI2010]连通数(bitset Tarjan 拓扑)

    题目链接 先缩点,对于scc之间贡献即为szscc[i]*szscc[j] 用f[i][j]表示scci是否能到sccj 拓扑排序,每次把now的f或上to的f 用bitset优化 //63888kb ...

  6. 【BZOJ】2208 [Jsoi2010]连通数

    [题意]给定n个点的有向图,求可达点对数(互相可达算两对,含自身).n<=2000. [算法]强连通分量(tarjan)+拓扑排序+状态压缩(bitset) [题解]这题可以说非常经典了. 1. ...

  7. bzoj 2208: [Jsoi2010]连通数【tarjan+拓扑+dp】

    我总觉得枚举点bfs也行-- tarjan缩点,记一下每个scc的size,bitset压一下scc里的点,然后按拓扑倒序向上合并到达状态,然后加ans的时候记得乘size #include<i ...

  8. BZOJ 2208 JSOI2010 连通数 Tarjan+拓扑排序

    题目大意:给定一个n个点的有向图,求有多少点对(x,y),使x沿边可到达y 设f[i][j]为从i到j是否可达 首先强联通分量中的随意两个点均可达 于是我们利用Tarjan缩点 缩点之后是一个拓扑图. ...

  9. bzoj2208:[Jsoi2010]连通数

    http://blog.csdn.net/u013598409/article/details/47037499 里面似乎有生成数据的... //我本来的想法是tarjan缩点之后然后将图遍历一遍就可 ...

随机推荐

  1. 修改/home内子目录的名字

    每次装Linux系统我都会直接安装英文版,虽然中文版方便使用,但是在终端里面会有诸多不便,例如/home目录里面那些子文件夹就是一个很大的麻烦了,不过如果你安装了中文版的系统,还是有办法改成英文的. ...

  2. php扩展SeasLog应用于 yii2 组件

    一.seaslog 简单介绍及使用原因 它是C 写的PHP扩展,性能很高,使用简单,能满足大部分简单的日志需求.(个人感觉) 其他优势请看-->https://github.com/Neeke/ ...

  3. KB奇遇记(6):搞笑的ERP项目团队

    早在我们来之前,KB公司这边就已经组建了ERP项目组了,当时IT就只有一个人,属网管出身.而关键用户分两种类型:专职关键用户和兼职关键用户.专职关键用户组织结构上已经调动到信息部,常驻在项目组里工作, ...

  4. POI-处理大Excel文件(xls)

    最近需要处理一个比较大的excel文件,但是poi在处理文件时会抛出OOM导致程序崩溃,查看官方文档看到可以以流式的方式读取excel避免读取大文件时的OOM.本文主要记述xls的处理. 环境模拟 先 ...

  5. Express与NodeJs创建服务器的两种方法

    NodeJs创建Web服务器 var http = require('http'); var server = http.createServer(function(req, res) { res.w ...

  6. windows 下odoo 不同版本安装运行问题

    在开发测试不同版本odoo时,总会遇到在同一浏览器下运行出错的状况.虽然可以把不同版本分属不同的端口,但是登录标识会入写用户本地浏览器cookie,由于cookie只匹配域名及路径但是不区分端口, 所 ...

  7. PLSQL DEVELOPER 使用的一些技巧【转】

    1.登录后默认自动选中My Objects 默认情况下,PLSQL Developer登录后,Brower里会选择All objects,如果你登录的用户是dba,要展开tables目录,正常情况都需 ...

  8. 关于hashmap的底层实现

    注:以下内容并非基于最新的jdk版本 q1:hashmap为什么叫hashmap? 答:hashmap基于hashtable(不是hashtable类)实现. q2:hashtable(不是hasht ...

  9. [笔记]FTRL与Online Optimization

    1. 背景介绍 最优化求解问题可能是我们在工作中遇到的最多的一类问题了:从已有的数据中提炼出最适合的模型参数,从而对未知的数据进行预测.当我们面对高维高数据量的场景时,常见的批量处理的方式已经显得力不 ...

  10. C语言memset学习

    #include <stdio.h> #include <memory.h> ]); //函数声明 void main(){ ]={{,,},{,,},{,,},{,,}};/ ...