Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

强联通分量分解

Posted by wzningjie at 2014-03-09 17:09:46 on Problem 2186
#include<iostream>
#include<vector>
#include<string.h>
using namespace std;
const int MAX_V=10020;
const int MAX_M=50020;
vector<int> vs;//后序遍历顺序的顶点列表
vector<int> G[MAX_V];//图的邻接表表示
vector<int> rG[MAX_V];//把边反向后的图
bool used[MAX_V];//访问标记
int V;//定点数
int cmp[MAX_V];//所属强连通分量的拓扑序
void add_edge(int from,int to)
{
	G[from].push_back(to);
	rG[to].push_back(from);
} 

void dfs(int v)
{
	used[v]=true;
	for(int i=0;i<G[v].size();i++)
	{
		if(!used[G[v][i]])
		dfs(G[v][i]);
	}
	vs.push_back(v);
}

void rdfs(int v,int k)
{
	used[v]=true;
	cmp[v]=k;
	for(int i=0;i<rG[v].size();i++)
	{
		if(!used[rG[v][i]])
		rdfs(rG[v][i],k);
	}
}

int scc()
{
	memset(used,0,sizeof(used));
	vs.clear();
	for(int v=0;v<V;v++)
	{
		if(!used[v])
		dfs(v);
	}
	memset(used,0,sizeof(used));
	int k=0;
	for(int i=vs.size()-1;i>=0;i--)
	{
		if(!used[vs[i]])
		rdfs(vs[i],k++);
	}
	return k;
} 
int N,M;
int A[MAX_M],B[MAX_M];
int main()
{
	cin>>N>>M;
	V=N;
	for(int i=0;i<M;i++)
	{
		cin>>A[i]>>B[i];
	    add_edge(A[i]-1,B[i]-1);
	}
	int n=scc();//统计备选解的个数 
	int u=0,num=0;
	for(int v=0;v<V;v++)
	{
		if(cmp[v]==n-1)
		{
			u=v;
			num++;
		}
	}
	//检查是否所有点可达 
	memset(used,0,sizeof(used));
	rdfs(u,0);
	for(int v=0;v<V;v++)
	{
		if(!used[v])
		{
			num=0;
			break;
		}
	}
	cout<<num<<endl;
	return 0;
	
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator