bzoj 2208: [Jsoi2010]连通数【tarjan+拓扑+dp】
2018-09-24 09:17
363 查看
我总觉得枚举点bfs也行……
tarjan缩点,记一下每个scc的size,bitset压一下scc里的点,然后按拓扑倒序向上合并到达状态,然后加ans的时候记得乘size
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> #include<bitset> using namespace std; const int N=2005; int n,h ,cnt,dfn ,low ,tot,s ,top,bl ,col,d ,a ,ans,si ; bool v ; char c ; bitset<N>f ; vector<pair<int,int> >b; struct qwe { int ne,no,to; }e[N*N]; void add(int u,int v) { cnt++; e[cnt].ne=h[u]; e[cnt].no=u; e[cnt].to=v; h[u]=cnt; } void tarjan(int u) { dfn[u]=low[u]=++tot; v[s[++top]=u]=1; for(int i=h[u];i;i=e[i].ne) { if(!dfn[e[i].to]) { tarjan(e[i].to); low[u]=min(low[u],low[e[i].to]); } else if(v[e[i].to]) low[u]=min(low[u],dfn[e[i].to]); } if(dfn[u]==low[u]) { col++; while(s[top]!=u) { bl[s[top]]=col; si[col]++; v[s[top--]]=0; } bl[s[top]]=col; si[col]++; v[s[top--]]=0; } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",c+1); for(int j=1;j<=n;j++) if(c[j]=='1') add(i,j); } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=n;i++) f[bl[i]][i]=1; for(int i=1;i<=cnt;i++) if(bl[e[i].no]!=bl[e[i].to]) b.push_back(make_pair(bl[e[i].no],bl[e[i].to])); memset(h,0,sizeof(h)); cnt=0; for(int i=0,len=b.size();i<len;i++) add(b[i].first,b[i].second),d[b[i].second]++; tot=0; queue<int>q; for(int i=1;i<=col;i++) if(!d[i]) q.push(i); while(!q.empty()) { int u=q.front(); q.pop(); a[++tot]=u; for(int i=h[u];i;i=e[i].ne) if(!(--d[e[i].to])) q.push(e[i].to); } for(int i=tot;i>=1;i--) { for(int j=h[a[i]];j;j=e[j].ne) f[a[i]]|=f[e[j].to]; ans+=f[a[i]].count()*si[a[i]]; } printf("%d\n",ans); return 0; }
相关文章推荐
- BZOJ 2208 [Jsoi2010]连通数 tarjan缩点+bitset优化DP
- BZOJ 2208 JSOI2010 连通数 Tarjan+拓扑排序
- BZOJ 2208 JSOI2010 连通数 Tarjan+拓扑排序
- [BZOJ2208][Jsoi2010]连通数(tarjan+topdp)
- BZOJ.2208.[JSOI2010]连通数(bitset Tarjan 拓扑)
- BZOJ 2208 [Jsoi2010]连通数 - Tarjan_SCC/Floyd+bitset优化
- [BZOJ2208][Jsoi2010]连通数(dfs||tarjan+拓扑序+dp)
- BZOJ 2208: [Jsoi2010]连通数 tarjan bitset
- [tarjan+bitset]BZOJ 2208——[Jsoi2010]连通数
- BZOJ 2208 JSOI 2010 连通数 Tarjan+bitset
- bzoj 2208: [Jsoi2010]连通数 (dfs|tarjan+bitset+拓扑序)
- 【BZOJ】2208 [Jsoi2010]连通数
- 【BZOJ】【2208】【JSOI2010】连通数
- [bzoj2208][Jsoi2010]连通数
- 2208: [Jsoi2010]连通数(tarjan + 状态压缩)
- BZOJ 2208: [Jsoi2010]连通数
- bzoj 2208: [Jsoi2010]连通数
- bzoj2208 [Jsoi2010]连通数(scc+bitset)
- BZOJ_2208_[Jsoi2010]连通数_强连通分量+拓扑排序+手写bitset
- 暴力【bzoj2208】: [Jsoi2010]连通数