tarjan算法--cojs 1298. 通讯问题
2016-05-14 17:03
363 查看
cojs 1298. 通讯问题
★ 输入文件:jdltt.in输出文件:
jdltt.out简单对比
时间限制:1 s 内存限制:128 MB
【题目描述】
一个篮球队有n个篮球队员,每个队员都有联系方式(如电话、电子邮件等)。但并不是每个队员的联系方式都公开,每个队员的联系方式只有一部分队员知道。问队员可以分成多少个小组,小组成员之间可以相互通知(包括一个队员一个组,表示自己通知自己)。【输入格式】
输入文件有若干行第一行,一个整数n,表示共有n个队员(2<=n<=100)下面有若干行,每行2个数a、b,a、b是队员编号,表示a知道b的通讯方式。
【输出格式】
输出文件有若干行第一行,1个整数m,表示可以分m个小组,下面有m行,每行有若干个整数,表示该小组成员编号,输出顺序按编号由小到大。
【样例输入】
121 32 12 43 23 43 54 6 5 46 47 47 87 128 78 910 911 10【样例输出】
81 2 3
4 6
5
7 8
9
10
11
12
/*先进行tarjan把所有的强连通分量放到几个数组中去,然后先对每个数组中的元素按字典序排序,然后把几个数组按照字典序排序,这样才能按照题目的意思输出*/ #include<iostream> using namespace std; #include<cstring> #include<cstdio> #include<stack> stack<int>sta; #include<algorithm> #define N 120 int dfn ,low ; int n,anst=0; struct Ans{ int a ; void sor(){sort(a+1,a+a[0]+1);} }ans ; struct Edge{ int v,last; }edge[N*N*2]; int topt=0,t=0; int head ; bool visited ={0},instack ={0}; void add_edge(int u,int v) { ++t; edge[t].v=v; edge[t].last=head[u]; head[u]=t; } void input() { scanf("%d",&n); int u,v; while(scanf("%d%d",&u,&v)==2) { add_edge(u,v); } } void tarjan(int k)/*tarjan算法,不解释*/ { visited[k]=true; dfn[k]=low[k]=++topt; sta.push(k); instack[k]=true; for(int l=head[k];l;l=edge[l].last) { if(!visited[edge[l].v]) { tarjan(edge[l].v); low[k]=min(low[k],low[edge[l].v]); } else { if(instack[edge[l].v]) low[k]=min(low[k],dfn[edge[l].v]); } } if(low[k]==dfn[k]) { anst++; int ys=sta.top(); instack[ys]=false; sta.pop(); while(ys!=k) { ans[anst].a[0]++; ans[anst].a[ans[anst].a[0]]=ys; ys=sta.top(); instack[ys]=false; sta.pop(); } instack[ys]=false; ans[anst].a[0]++; ans[anst].a[ans[anst].a[0]]=ys; } } int cmp(Ans p,Ans q) { for(int i=1;i<=p.a[0]&&i<=q.a[0];++i) { if(p.a[i]<q.a[i]) return true; } return false; } int main() { freopen("jdltt.in ","r",stdin); freopen("jdltt.out","w",stdout); input(); for(int i=1;i<=n;++i) if(!visited[i]) tarjan(i); for(int i=1;i<=anst;++i) ans[i].sor();/*对每个强连通分量的元素排序,注意结构体函数的妙用*/ sort(ans+1,ans+anst+1,cmp);/*再把所有的强连通分量排序*/ printf("%d\n",anst); for(int i=1;i<=anst;++i) { for(int j=1;j<=ans[i].a[0];++j) printf("%d ",ans[i].a[j]); printf("\n"); } fclose(stdin);fclose(stdout); return 0; }
相关文章推荐
- 火狐浏览器下 js给img标签赋值:base64编码
- [未完整]谈js中的作用域链和闭包
- js图片转base64编码压缩上传
- jsp页面 报core 找不到
- Json数据由于数组下标未重置导致的格式问题
- js——全选框 checkbox
- cojs 安科赛斯特 题解报告
- 利用Abot爬虫和visjs 呈现漫威宇宙
- cJSON序列化工具解读一(结构剖析)
- JavaScript之web通信
- JSP EL表达式详细介绍
- 谈谈小白理解的js中的原型链问题
- JSP——JSP介绍以及运行原理
- 易被忽视的js事件问题总结
- Javascript复习第五天二级联动菜单
- js判断是否为同样的或者相邻的数字
- js中容易被忽视的事件问题总结
- JSP取得绝对路径
- EL表达式和JSTL
- Json解析详细教程