SSL 2344 洛谷 2835 信息学奥赛一本通 1383 刻录光盘
2018-03-16 20:13
344 查看
洛谷请关掉优化
题目
求有多少个连通块分析
floyd+并查集floyd代码
#include <cstdio> #include <cctype> #include <cstring> using namespace std; int n,m,ans,f[201],x; bool v[201],a[201][201]; int in(){ int ans=0; char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) ans=ans*10+c-48,c=getchar(); return ans; } int main(){ n=in(); for (int i=1;i<=n;i++) while (x=in(),x) a[i][x]=1; for (int k=1;k<=n;k++) for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) a[i][j]=a[i][j]||(a[i][k]&&a[k][j]);//图的连通性 for (int i=1;i<=n;i++) f[i]=i; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) f[j]=(a[i][j])?f[i]:f[j];//连通吗 for (int i=1;i<=n;i++) if (f[i]==i) ans++;//并查集 printf("%d",ans); return 0; }
分析
kosaraju#include <cstdio> #include <cstring> using namespace std; int n,m,ans,f[201],x; bool v[201],a[201][201]; void dfs1(int x){ v[x]=1; for (int i=1;i<=n;i++) if (a[x][i]&&!v[i]) dfs1(i); f[++m]=x;//记录退出的顺序 } void dfs2(int x){ v[x]=1; for (int i=1;i<=n;i++) if (a[x][i]&&!v[i]) dfs2(i); } int main(){ scanf("%d",&n); for (int i=1;i<=n;i++) while (scanf("%d",&x),x) a[i][x]=1; for (int i=1;i<=n;i++) if (!v[i]) dfs1(i); memset(v,0,sizeof(v)); for (int i=m;i>=1;i--) if (!v[f[i]]) ans++,dfs2(f[i]);//拓扑排序过 printf("%d",ans); return 0; }
分析
tarjan#include <cstdio> #include <cstring> using namespace std; struct node{ int x,y,next; }e[20363]; int n,m,ans,f[201],rd[201],g,k,ls[201],low[201]; int color[201],tim,cnum,dfn[201],sta[201],top; bool v[201]; void tarjan(int x){ dfn[x]=low[x]=++tim; sta[++top]=x; v[x]=1; int t=ls[x]; while (t){ if (!dfn[e[t].y]){//没有被访问过 tarjan(e[t].y); low[x]=(low[x]>low[e[t].y])?low[e[t].y]:low[x]; } else if (v[e[t].y]) //走过 low[x]=(low[x]>low[e[t].y])?low[e[t].y]:low[x]; t=e[t].next; } if (dfn[x]==low[x]){//形成连通图 v[x]=0; color[x]=++cnum; do{ v[sta[top]]=0; color[sta[top]]=cnum; } while(sta[top--]!=x);//出栈 } } int main(){ scanf("%d",&n); for (int i=1;i<=n;i++) while (scanf("%d",&g),g) e[++k].x=i,e[k].y=g,e[k].next=ls[e[k].x],ls[e[k].x]=k; //邻接表 for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i); //没有被访问过 for (int i=1;i<=k;i++) if (color[e[i].x]!=color[e[i].y]) rd[color[e[i].y]]++;//不经过 for (int i=1;i<=cnum;i++) if (!rd[i]) ans++;//入度为0 printf("%d",ans); return 0; }
相关文章推荐
- SSL 2331 洛谷 1717 信息学奥赛一本通 1373 鱼塘钓鱼 贪心
- SSL 2331 信息学奥赛一本通 1373 洛谷 1717 鱼塘钓鱼 动态规划
- SSL-2344 刻录光盘
- SSL 1411 洛谷 2085 信息学奥赛一本通 1370
- 洛谷 1455 信息学奥赛一本通 1387 SSL 2347 搭配购买
- 洛谷 2814 SSL 2343 信息学奥赛一本通 1388 家谱
- SSL_2344 刻录光盘
- 最长公共子序列(信息学奥赛一本通1297 ssl 1463)
- (信息学奥赛一本通 1304 洛谷 1025)数的划分
- SSL 2342 信息学奥赛一本通 1386 打击犯罪
- 关于luoguP2835 刻录光盘 的反思
- 【luogu2835】 刻录光盘
- 洛谷P2835 刻录光盘
- 信息学奥赛一本通 1347 SSL 2340 格子游戏
- 洛谷 1892 信息奥赛一本通 1385 SSL 2341 团伙
- 洛谷 P2835 刻录光盘
- 洛谷P2835 刻录光盘 [2017年6月计划 强连通分量02]
- 新光盘不能直接用cdrecord或者wodim进行刻录,解决方法
- Solaris 10下如何刻录光盘
- [置顶] 信息学奥赛一本通(C++版) 第二部分 基础算法 第二章 数据排序