Problem:
C: 同値命題

問題

$N$ 個の命題があり, それぞれ $1, 2, \cdots,N$ という名前がついている.

また, 命題に関する情報が $M$ 個与えられる. $i$ 番目の情報は「$a_i$ $b_i$」という形式で与えられ, これは $a_i$ ならば $b_i$ であることを表す.（「ならば」は論理包含であり、推移律が成り立つ）

各命題 $i$ に対して $i$ と同値な命題を全て昇順に出力せよ.

ただし命題 $i$ と命題 $i$ は常に同値である.

命題 $X$ と命題 $Y$ が同値とは,「$X$ ならば $Y$」かつ「$Y$ ならば $X$」のことである.

制約

入力値は全て整数である.

$ 2 \leq N \leq 300$

$ 1 \leq M \leq N(N - 1)$

$ a_i \neq b_i $

$1 \leq a_i, b_i \leq N $

入力形式

入力は以下の形式で与えられる.

$N\ M$

$a_1\ b_1$

$a_2\ b_2$

$\vdots$

$a_M\ b_M$

出力

$i$ 行目には命題 $i$ と同値である命題を昇順に空白区切りですべて出力せよ. また, 各行の末尾に改行を出力せよ.

サンプル

サンプル入力 1

5 2
1 2
2 1

サンプル出力 1

1 2
1 2
3
4
5

サンプル入力 2

3 3
1 2
2 3
3 1

サンプル出力 2

1 2 3
1 2 3
1 2 3

サンプル入力 3

6 7
1 2
1 3
2 6
3 4
4 5
5 3
6 2

サンプル出力 3

1
2 6
3 4 5
3 4 5
3 4 5
2 6

Solution in C (judge verdict: Accepted)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

typedef struct{
	int N,M;
	int **AB;
}DATA;//input

void frac(DATA data,int *C,int a){
	for(int i=1;i<data.N;i++){
		if(C[i]==0){
			if(data.AB[a][i]==1){
				C[i]=1;
				frac(data,C,i);
			}
		}
	}
}

void show(int **C,int N){
	int D_count=0;
	int *D=(int*)malloc(sizeof(int)*N);
	for(int i=0;i<N;i++){
			D[i]=0;
		
	}
	for(int i=1;i<N;i++){
		D_count=0;
		for(int j=1;j<N;j++){
			if((C[i][j]==1) && (C[j][i]==1)){
				D[D_count++]=j;
			}
		}
		for(int j=0;j<D_count;j++){
			printf("%d",D[j]);
			if(j==(D_count-1)){
				printf("\n");
			}else{
				printf(" ");
			}
		}
	}
}

void calc(DATA data){
	int N=data.N;
	int **C=(int**)malloc(sizeof(int*)*N);
	for(int i=0;i<N;i++){
		C[i]=(int*)malloc(sizeof(int)*N);
		for(int j=0;j<N;j++){
			C[i][j]=0;
		}
	}

	for(int i=1;i<N;i++){
		frac(data,C[i],i);
		C[i][i]=1;
	}

	show(C,N);

}

int main(){
	
	DATA data;

	scanf("%d %d",&data.N,&data.M);
	data.N++;
	
	data.AB=(int**)malloc(sizeof(int*)*data.N);
	for(int i=0;i<data.N;i++){
		data.AB[i]=(int*)malloc(sizeof(int)*data.N);
		for(int j=0;j<data.N;j++){
			data.AB[i][j]=0;
		}
	}
	int a,b;
	for(int i=0;i<data.M;i++){
		scanf("%d %d",&a,&b);
		data.AB[a][b]=1;
	}

	calc(data);

	return 0;
}