记录编号 |
56878 |
评测结果 |
AAAAA |
题目名称 |
通讯问题 |
最终得分 |
100 |
用户昵称 |
cstdio |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.001 s |
提交时间 |
2013-04-04 14:42:35 |
内存使用 |
0.33 MiB |
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<deque>
#include<cmath>
#include<algorithm>
using namespace std;
const int SIZEN=101;
//注意:节点下标是1~n
int n;//节点数
bool c[SIZEN][SIZEN]={0};//邻接矩阵
int dfn[SIZEN]={0};//时间戳
int low[SIZEN]={0};//能追溯到的最早时间戳
int index=0;//时间变量
deque<int> st;//栈
bool instack[SIZEN]={0};//是否在栈中
int comsum=0;
int belong[SIZEN]={0};//每个节点在哪个分量内
void Tarjan(int x){//访问x的子树
if(dfn[x]) return;
dfn[x]=low[x]=++index;//访问过的点dfn值>0
st.push_back(x);
instack[x]=true;
int i;
for(i=1;i<=n;i++){
if(i==x||!c[x][i]) continue;
if(!dfn[i]){//i节点未被访问
Tarjan(i);
low[x]=min(low[x],low[i]);
}
else if(instack[i]){//i节点在栈中
low[x]=min(low[x],dfn[i]);
}
}
if(dfn[x]==low[x]){//x是强连通分量的一个"根"
comsum++;
int temp;
do{
temp=st.back();
belong[temp]=comsum;
instack[temp]=false;
st.pop_back();
if(st.empty()||temp==x) break;
}while(temp!=x);
}
}
void output(void){
int i,j;
printf("%d\n",comsum);
bool used[SIZEN]={0};
for(i=1;i<=n;i++){
if(used[i]) continue;
for(j=1;j<=n;j++){
if(belong[j]==belong[i]){
printf("%d ",j);
used[j]=true;
}
}
printf("\n");
}
}
int main(){
freopen("jdltt.in","r",stdin);
freopen("jdltt.out","w",stdout);
scanf("%d",&n);
int a,b;
while(!cin.eof()){
cin>>a>>b;
c[a][b]=1;
}
for(int i=1;i<=n;i++){
Tarjan(i);
}
output();
return 0;
}