有向图缩点

/*****************************\
| 有向图缩点
| CALL:void reduce_point();
| N,M分别为点数边数
| fa[]记录缩点后每个点属于哪个点
\*****************************/
int f_min(int x,int y){
	return x<y?x:y;
}
struct Edge{
	int u,v,next,w;
};
Edge edge[100000];
int head[50000],en;
void insert(int u,int v,int w){
	edge[en].u=u;edge[en].v=v;edge[en].w=w;
	edge[en].next=head[u];head[u]=en++;
}
int N,M;
void get_data(){
	memset(head,-1,sizeof(head));
	en=0;
	int u,v,w;
	while(M--){
		scanf("%d%d%d",&u,&v,&w);
		insert(u,v,w);
	}
}
int fa[50000],stk[50000],sn,time,mint[50000];
bool instk[50000],mark[50000];
void dfs(int u){
	int now;
	now=mint[u]=time++;
	stk[sn++]=u;
	instk[u]=1;
	int i,v;
	for(i=head[u];i!=-1;i=edge[i].next){
		v=edge[i].v;
		if(mark[v])continue;
		if(!instk[v])dfs(v);
		mint[u]=f_min(mint[u],mint[v]);
	}
	if(mint[u]==now){
		while(stk[sn-1]!=u){
			fa[stk[sn-1]]=u;//stk[sn-1]属于u点,如有需要可在此保存
			mark[stk[sn-1]]=1;
			sn--;
		}
		fa[u]=u;mark[u]=1;sn--;
	}
}
void reduce_point(){
	memset(mark,0,sizeof(mark));
	memset(instk,0,sizeof(instk));
	sn=time=0;
	int i;
	for(i=0;i<N;i++){
		if(mark[i])continue;
		dfs(i);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值