2208: [Jsoi2010]连通数 - BZOJ
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。
看到这题然后马上打了一个tarjan
然后对每一个强连通分量dfs,A了之后感觉有点奇怪,这个复杂度是多少来着,我好像算不出来,果断百度题解
然后大囧。。。。。。怎么好像正解是tarjan+拓扑排序+状态压缩,只搜到了一个和我一样的做法
然后我想到这样做其实可以随随便便卡掉,还是n三方,于是又打了一遍正解,加个拓扑和状态压缩
const
maxn=;
var
first,c,sum,dfn,low,z:array[..maxn*]of longint;
next,last:array[..maxn*maxn*]of longint;
flag:array[..maxn*]of boolean;
f:array[..maxn,..maxn]of boolean;
n,cnt,tot,ans,time,s:longint; procedure insert(x,y:longint);
begin
inc(tot);
last[tot]:=y;
next[tot]:=first[x];
first[x]:=tot;
end; procedure dfs(x:longint);
var
i:longint;
begin
inc(time);
dfn[x]:=time;
low[x]:=time;
inc(s);
z[s]:=x;
flag[x]:=true;
i:=first[x];
while i<> do
begin
if dfn[last[i]]= then
begin
dfs(last[i]);
if low[last[i]]<low[x] then low[x]:=low[last[i]];
end
else
if flag[last[i]] and (low[last[i]]<low[x]) then low[x]:=low[last[i]];
i:=next[i];
end;
if low[x]=dfn[x] then
begin
inc(cnt);
while z[s+]<>x do
begin
inc(sum[cnt]);
c[z[s]]:=cnt;
flag[z[s]]:=false;
dec(s);
end;
end;
end; procedure init;
var
i,j:longint;
cc:char;
begin
readln(n);
for i:= to n do
begin
for j:= to n do
begin
read(cc);
if cc='' then insert(i,j);
end;
readln;
end;
for i:= to n do
if dfn[i]= then dfs(i);
for i:= to n do
begin
j:=first[i];
while j<> do
begin
if f[c[i],c[last[j]]]=false then
begin
insert(n+c[i],n+c[last[j]]);
f[c[i],c[last[j]]]:=true;
end;
j:=next[j];
end;
end;
end; function dfs2(x:longint):longint;
var
i:longint;
begin
dfs2:=sum[x-n];
flag[x]:=true;
i:=first[x];
while i<> do
begin
if flag[last[i]]=false then inc(dfs2,dfs2(last[i]));
i:=next[i];
end;
end; procedure work;
var
i,j:longint;
begin
for i:= to cnt do
begin
for j:= to cnt do
flag[j+n]:=false;
inc(ans,sum[i]*dfs2(i+n));
end;
writeln(ans);
end; begin
init;
work;
end.
const
maxn=;
var
first,c,sum,dfn,low,z,d:array[..maxn*]of longint;
next,last:array[..maxn*maxn*]of longint;
flag:array[..maxn*]of boolean;
ff:array[..maxn,..maxn]of boolean;
n,cnt,tot,ans,time,s:longint; procedure insert(x,y:longint);
begin
inc(tot);
last[tot]:=y;
next[tot]:=first[x];
first[x]:=tot;
end; procedure dfs(x:longint);
var
i:longint;
begin
inc(time);
dfn[x]:=time;
low[x]:=time;
inc(s);
z[s]:=x;
flag[x]:=true;
i:=first[x];
while i<> do
begin
if dfn[last[i]]= then
begin
dfs(last[i]);
if low[last[i]]<low[x] then low[x]:=low[last[i]];
end
else
if flag[last[i]] and (low[last[i]]<low[x]) then low[x]:=low[last[i]];
i:=next[i];
end;
if low[x]=dfn[x] then
begin
inc(cnt);
while z[s+]<>x do
begin
inc(sum[cnt]);
c[z[s]]:=cnt;
flag[z[s]]:=false;
dec(s);
end;
end;
end; procedure init;
var
i,j:longint;
cc:char;
begin
readln(n);
for i:= to n do
begin
for j:= to n do
begin
read(cc);
if cc='' then insert(i,j);
end;
readln;
end;
for i:= to n do
if dfn[i]= then dfs(i);
for i:= to n do
begin
j:=first[i];
while j<> do
begin
if (ff[c[i],c[last[j]]]=false) and (c[i]<>c[last[j]]) then
begin
insert(n+c[i],n+c[last[j]]);
inc(d[c[last[j]]]);
ff[c[i],c[last[j]]]:=true;
end;
j:=next[j];
end;
end;
end; var
q:array[..maxn]of longint;
f:array[..maxn,..]of longint;
l,r:longint; procedure work;
var
i,j,k,tmp:longint;
begin
l:=;
r:=;
for i:= to cnt do
if d[i]= then
begin
inc(r);
q[r]:=i;
end;
while l<=r do
begin
j:=first[q[l]+n];
while j<> do
begin
dec(d[last[j]-n]);
if d[last[j]-n]= then
begin
inc(r);
q[r]:=last[j]-n;
end;
j:=next[j];
end;
inc(l);
end;
for i:=r downto do
begin
f[q[i],q[i] div ]:=<<(q[i]mod );
j:=first[q[i]+n];
while j<> do
begin
for k:= to cnt div do
f[q[i],k]:=f[q[i],k]or f[last[j]-n,k];
j:=next[j];
end;
end;
for i:= to cnt do
begin
tmp:=;
for j:= to cnt do
if f[i,j div ] and (<<(j mod ))> then inc(tmp,sum[j]);
inc(ans,tmp*sum[i]);
end;
writeln(ans);
end; begin
init;
work;
end.
2208: [Jsoi2010]连通数 - BZOJ的更多相关文章
- BZOJ 2208: [Jsoi2010]连通数 tarjan bitset
2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- BZOJ 2208: [Jsoi2010]连通数( DFS )
n只有2000,直接DFS就可以过了... -------------------------------------------------------------------------- #in ...
- bzoj 2208 [Jsoi2010]连通数
2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 输入数据第一行是图顶点的数量,一个正整数N ...
- 2208: [Jsoi2010]连通数
2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1371 Solved: 557[Submit][Status ...
- BZOJ.2208.[JSOI2010]连通数(bitset Tarjan 拓扑)
题目链接 先缩点,对于scc之间贡献即为szscc[i]*szscc[j] 用f[i][j]表示scci是否能到sccj 拓扑排序,每次把now的f或上to的f 用bitset优化 //63888kb ...
- 【BZOJ】2208 [Jsoi2010]连通数
[题意]给定n个点的有向图,求可达点对数(互相可达算两对,含自身).n<=2000. [算法]强连通分量(tarjan)+拓扑排序+状态压缩(bitset) [题解]这题可以说非常经典了. 1. ...
- bzoj 2208: [Jsoi2010]连通数【tarjan+拓扑+dp】
我总觉得枚举点bfs也行-- tarjan缩点,记一下每个scc的size,bitset压一下scc里的点,然后按拓扑倒序向上合并到达状态,然后加ans的时候记得乘size #include<i ...
- BZOJ 2208 JSOI2010 连通数 Tarjan+拓扑排序
题目大意:给定一个n个点的有向图,求有多少点对(x,y),使x沿边可到达y 设f[i][j]为从i到j是否可达 首先强联通分量中的随意两个点均可达 于是我们利用Tarjan缩点 缩点之后是一个拓扑图. ...
- bzoj2208:[Jsoi2010]连通数
http://blog.csdn.net/u013598409/article/details/47037499 里面似乎有生成数据的... //我本来的想法是tarjan缩点之后然后将图遍历一遍就可 ...
随机推荐
- AsyncTask实现的原理和适用的优缺点
AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI ...
- SQL SERVER 2008 R2 错误代码 17000 - 17999
错误 严重性 是否记录事件 说明(消息正文) 17000 10 否 用法: sp_autostats <table_name> [, {ON|OFF} [, <index_name& ...
- PHP实现前台同步显示后台任务进度
一次批量发送几千条短信. 如果直接在后台循环执行虽然可行,但是前台操作用户就只能坐着空等,完全看不到后台执行结果,所以考虑能不能有一种办法可以在php后台执行过程中同时在前台显示后台执行任务进度呢. ...
- JQuery 动态添加onclick事件
$('#div_id').click(function(){ show(1,2,this); });
- 找不到命名空间命名空间:System.Windows.Forms
System.Windows.Forms在system.windows.forms.dll中.需要添加引用.在解决方案资源管理器中的引用上单击右键,选择添加引用.找到System.windows.fo ...
- Row_Number实现分页(适用SQL)
1:首先是 select ROW_NUMBER() over(order by id asc) as 'rowNumber', * from table1 生成带序号的集合 2:再查询该集合的 第 1 ...
- IE8 textarea 滚动条定位不准解决方法
工作中遇到一个bug: IE8 下textarea 如果带滚动条(height:100px;overflow:scroll-y;),内容高度超过可视区域之后,输入文字,滚动条位置会乱跳. 开始以为是j ...
- 《DNS服务缓存的建立》RHEL6
安装dns软件包: 启动dns服务器 配置本地服务器dns域名解析: 查看dns的服务的端口是否打开: 解析百度测试: 安装dns缓存包: 再次访问解析百度
- 《用户和组的管理》Redhat6.3
linux下有三类用户: 1.超级用户 :root 具有操作系通的一切权限 uid 0 2.普通用户:普通用户具有操作系统有限的权限 uid 500-6000 3.伪用户 :是为了方便系统管理,满足 ...
- C# 在子线程中创建不会阻塞执行窗体
可以参考”C# 对 Windows 窗体控件进行线程安全调用“一文来看. 在做网络连接程序的时候碰到一个问题:每当连接到来时,都创建一个新的接收线程,而该接收线程在接收到消息时,可以创建一个新的对话窗 ...