poj2186 有向图强连通缩点

真心不能用vector

同样的代码,用vector500+ms,用邻接表32ms

#include <iostream>
#include <cstring>
#include <cstdio>
#include <math.h>
#include <cstdlib>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
int n,m ;
#define N 10500
#define M 60000
//vector<int>e[N];
int dfn[N],low[N],cnt,sta[N],top,scc[N],vis[N],scc_cnt;
int num[N],ans;
int edge[M],adj[M],head[N];

void tarjan(int u)
{
	dfn[u]=low[u]=++cnt;
	sta[top++]=u;
	vis[u]=1;
	for(int i=head[u];i!=-1;i=adj[i])
	{
		int v=edge[i];
		if(!dfn[v])
		{
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(vis[v])
			low[u]=min(low[u],dfn[v]);
	}
	if(dfn[u]==low[u])
	{
		++scc_cnt;
		int i;
		do{
			i=sta[--top];
			scc[i]=scc_cnt;
			vis[i]=0;
		}while(i!=u);
	}
}

int out[N],e;

void addedge(int u,int v)
{
	edge[e]=v;adj[e]=head[u];head[u]=e++;;
}
int main ()
{
	memset(head,-1,sizeof(head));
	e=0;
	scanf("%d%d",&n,&m);
	int u,v;
	for(int i=1;i<=m;++i)
	{
		scanf("%d%d",&u,&v);
		addedge(u,v);
		//e[u].push_back(v);
	}
	for(int i=1;i<=n;++i)
		if(!dfn[i])
		{
			tarjan(i);
		}
	
	for(int u=1;u<=n;++u)
	{
		num[scc[u]]++;
		for(int i=head[u];i!=-1;i=adj[i])
		{
			int v=edge[i];
			if(scc[u]!=scc[v])
				out[scc[u]]++;
		}
	}
	int x,c=0;
	for(int i=1;i<=scc_cnt;++i)
	{
		if(out[i]==0)
			x=i,c++;
	}
	if(c>1)
		printf("0\n");
	else printf("%d\n",num[x]);
	//system("pause");
	return 0;
}


你可能感兴趣的:(poj2186 有向图强连通缩点)