bzoj 2208: [Jsoi2010]连通数 (dfs|tarjan+bitset+拓扑序)
来源:互联网 发布:超星网络选修课怎么刷 编辑:程序博客网 时间:2024/05/22 03:32
2208: [Jsoi2010]连通数
Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2365 Solved: 1001
[Submit][Status][Discuss]
Description
Input
输入数据第一行是图顶点的数量,一个正整数N。 接下来N行,每行N个字符。第i行第j列的1表示顶点i到j有边,0则表示无边。
Output
输出一行一个整数,表示该图的连通数。
Sample Input
3
010
001
100
010
001
100
Sample Output
9
HINT
对于100%的数据,N不超过2000。
Source
第一轮
题解:dfs
数据范围很小,直接暴力即可。
貌似正解是tarjan+拓扑序
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define N 5000003using namespace std;int n,m;int point[N],next[N],v[N],ans,vis[N],num,tot;char s[3003];void add(int x,int y){tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y;}void dfs(int now,int x){vis[x]=now; ans++;for (int i=point[x];i;i=next[i]) if (vis[v[i]]<now) dfs(now,v[i]);}int main(){scanf("%d",&n);for (int i=1;i<=n;i++) {scanf("%s",s+1);for (int j=1;j<=n;j++) if (s[j]=='1') add(i,j);}for (int i=1;i<=n;i++) dfs(i,i);printf("%d\n",ans);}
tarjan+bitset+拓扑序
tarjan缩点后,每次块内的点可以相互到达,ans+=num[i]*num[i],num[i]表示的是强连通块内点的个数。
然后考虑块与块之间的影响,按照拓扑序进行更新,然后用bitset记录块与块之间的到达关系,记录答案即可。
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<queue>#include<bitset>#define N 5000003#define M 2003using namespace std;int n,m,top;int point[M],next[N],v[N],vis[M],num[N],tot,cnt1,sum[N],ans,sz,map[M][M];int x[N],y[N],cnt,dfsn[M],st[N],belong[M],ins[M],low[M],outs[M];char s[3003];bitset<M> mark[M];void add(int x,int y){tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y;//cout<<x<<" "<<y<<endl;}void tarjan(int x){low[x]=dfsn[x]=++sz;ins[x]=1; st[++top]=x;for (int i=point[x];i;i=next[i]) { int j=v[i]; if (!dfsn[j]) tarjan(j),low[x]=min(low[x],low[j]); else if(ins[j]) low[x]=min(low[x],dfsn[j]); }if(low[x]==dfsn[x]) {++cnt;int j;do{j=st[top--]; num[cnt]++;belong[j]=cnt; ins[j]=0;}while(j!=x);sum[cnt]=num[cnt];ans+=num[cnt]*num[cnt];}}int main(){freopen("a.in","r",stdin);freopen("my.out","w",stdout);scanf("%d",&n);for (int i=1;i<=n;i++) {scanf("%s",s+1);for (int j=1;j<=n;j++) if (s[j]=='1') add(i,j),x[++cnt1]=i,y[cnt1]=j;}for (int i=1;i<=n;i++) if (!dfsn[i]) tarjan(i);tot=0;memset(point,0,sizeof(point));memset(next,0,sizeof(next));memset(ins,0,sizeof(ins));//cout<<endl;for (int i=1;i<=cnt1;i++) if (belong[x[i]]!=belong[y[i]]) { int t=belong[x[i]]; int t1=belong[y[i]]; map[t][t1]=1; }for (int i=1;i<=cnt;i++) for (int j=1;j<=cnt;j++) if (map[i][j]) add(i,j),ins[j]++,outs[i]++;queue<int> p; for (int i=1;i<=cnt;i++) if (!ins[i]) p.push(i);for (int i=1;i<=cnt;i++) mark[i][i]=1;while (!p.empty()) {int now=p.front(); p.pop();int t=0;for (int i=1;i<=cnt;i++) if(mark[now][i]&&i!=now) t+=num[i];ans+=t*num[now];for (int i=point[now];i;i=next[i]) { mark[v[i]]|=mark[now]; ins[v[i]]--; if (!ins[v[i]]) p.push(v[i]); }}printf("%d\n",ans);}
0 0
- bzoj 2208: [Jsoi2010]连通数 (dfs|tarjan+bitset+拓扑序)
- 【bzoj 2208】[Jsoi2010]连通数(dfs||Tarjan算法+拓扑序+dp)
- [BZOJ2208][Jsoi2010]连通数(dfs||tarjan+拓扑序+dp)
- [tarjan+bitset]BZOJ 2208——[Jsoi2010]连通数
- BZOJ 2208 JSOI2010 连通数 Tarjan+拓扑排序
- bzoj 2208 [Jsoi2010]连通数 bitset
- bzoj 2208: [Jsoi2010]连通数 拓扑排序+强连通分量+bitset
- bzoj2208 [Jsoi2010]连通数(tarjan缩点+拓扑排序+bitset传递闭包)
- BZOJ 2208 [Jsoi2010]连通数 tarjan缩点+bitset优化DP
- [Tarjan+Bitset]BZOJ2208: [Jsoi2010]连通数
- 2208: [Jsoi2010]连通数(Trajan+bitset)
- bzoj 2208: [Jsoi2010]连通数
- 【BZOJ 2208】 [Jsoi2010]连通数
- bzoj 2208: [Jsoi2010]连通数
- bzoj 2208: [Jsoi2010]连通数
- BZOJ 2208: [Jsoi2010]连通数
- BZOJ 2208 [Jsoi2010]连通数
- BZOJ 2208: [Jsoi2010]连通数
- Matlab random(转)
- 在eclipse中 自定义maven配置
- python内置容器之元组
- H264 RTP 封包原理
- React官方文档--Composition vs Inheritance
- bzoj 2208: [Jsoi2010]连通数 (dfs|tarjan+bitset+拓扑序)
- CentOS7.2下安装VSCode1.6.1后启动失败
- java文件上传和下载
- Win10 Docker 安装使用
- Android蓝牙打印机,带你真正了解各种打印格式
- 《JVM学习系列》三.HotSpot虚拟机对对象的回收
- 删除所有独特的元素
- javascript实现动画的联动
- Android iw 使用方法