POJ 1236 Network of Schools
2015-08-28 12:58
429 查看
之前对Kosaraju_Algorithm理解有误,现在彻底明白了。
Kosaraju_Algorithm:
• step1:对原图G进行深度优先遍历,记录每个节点的离开时间。形成了一个森林(很多树)。
• step2:选择具有最晚离开时间的顶点,对反图GT进行遍历,删除能够遍历到的顶点,这些顶点构成一个强连通分量。
• step3:如果还有顶点没有删除,继续step2,否则算法结束。
对于这个题目,第一问的答案就是缩点之后入度为0的节点的个数,第二问就是max(入度为0的结点个数,出入为0的结点个数)
如果本来就只有一个强连通分量,那么输出1 0就可以了。
Kosaraju_Algorithm:
• step1:对原图G进行深度优先遍历,记录每个节点的离开时间。形成了一个森林(很多树)。
• step2:选择具有最晚离开时间的顶点,对反图GT进行遍历,删除能够遍历到的顶点,这些顶点构成一个强连通分量。
• step3:如果还有顶点没有删除,继续step2,否则算法结束。
对于这个题目,第一问的答案就是缩点之后入度为0的节点的个数,第二问就是max(入度为0的结点个数,出入为0的结点个数)
如果本来就只有一个强连通分量,那么输出1 0就可以了。
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespace std; const int maxn=105; int Dfn[maxn],U[100000],V[100000],Belong[maxn]; int In[maxn],Out[maxn],flag[maxn]; struct Point { int id,dfn; } point[maxn]; vector<int>G[maxn]; vector<int>FG[maxn]; int N,Tot; int Sum,Block,in,out; void init() { for(int i=0; i<maxn; i++) G[i].clear(); for(int i=0; i<maxn; i++) FG[i].clear(); memset(Dfn,0,sizeof Dfn); memset(In,0,sizeof In); memset(Out,0,sizeof Out); memset(flag,0,sizeof flag); Tot=0;//时间戳 Sum=0;//边的数目 Block=0;//强连通分量的数目 in=0;//统计入度为0的点的数目 out=0;//统计出度为0的点的数目 } bool cmp(const Point&a,const Point&b) { return a.dfn>b.dfn; } void Dfs(int now) { flag[now]=1; for(int i=0; i<G[now].size(); i++) if(!flag[G[now][i]]) Dfs(G[now][i]); Tot++; Dfn[now]=Tot; } void dfs(int now) { Belong[now]=Block; for(int i=0; i<FG[now].size(); i++) if(!Belong[FG[now][i]]) dfs(FG[now][i]); } int main() { while(~scanf("%d",&N)) { init(); for(int i=1; i<=N; i++) { while(1) { int v; scanf("%d",&v); if(!v) break; Sum++; U[Sum]=i; V[Sum]=v; G[i].push_back(v); FG[v].push_back(i); } } for (int i = 1; i <= N; i++) if (!flag[i]) Dfs(i); for(int i=0; i<N; i++) point[i].id=i+1, point[i].dfn=Dfn[i+1]; sort(point,point+N,cmp); for(int i=0; i<N; i++) if(!Belong[point[i].id]) Block++,dfs(point[i].id); for(int i=1; i<=Sum; i++) if(Belong[U[i]]!=Belong[V[i]]) Out[Belong[U[i]]]++,In[Belong[V[i]]]++; for(int i=1; i<=Block; i++) { if(!In[i]) in++; if(!Out[i]) out++; } if(Block==1) printf("1\n0\n"); else printf("%d\n%d\n",in,max(in,out)); } return 0; }
相关文章推荐
- param_check_int的实现解析
- 新添一种字库
- 7-days-asp-dotnet-mvc-day1
- Windows平台上,使用eclipse连接到DB2数据库
- 刚刚开始学java,我的第一个比较好一点的Java程序。ps:只要努力,就会有收获
- 全球资本大整合,皓顿斩获千万融资!
- poj 1698 Alice's Chance 【最大流 判断是否满流】
- 如何正确的使用json?如何在.Net中使用json?
- 浅谈四种XML文件生成与解析方法
- 2.tomcat下安装solr5及数据库索引
- u3d_shader_surface_shader_6
- URI和URL的区别
- dtree详解
- import org.cocos2dx.lib cannot be resolved 解决方法
- 【JSON】JavaScript删除json元素
- AsyncTask of Android Android系统中的异步任务
- www-authenticate与BASE-64认证技术
- 浅谈XML
- Swift 随机字符串和字符串中间截取
- www-authenticate与BASE-64认证技术