Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 18198 | Accepted: 7330 |
Description
Input
Output
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
题意:问那个牛最受欢迎。即问有多少个点其他任何点都能到达。单向连通。
思路:强连通缩点。求出度为零的点(强连通分量),这个点只能有一个,输出这个强连通分量重点的个数,否则输出0。
tarjian算法与gabow算法,二者的思想是相同的,只是一个用数组存,一个是用的栈来维护的那个追溯到的父节点。据说:Galow算法更省时。
tarjian算法代码:
#include
#include
#include
#include
using namespace std;
#define max_n 10005
#define max_e 250002
#define inf 99999999
int stack[max_n],top;//栈
int isInStack[max_n];//是否在栈内
int low[max_n],dfn[max_n],tim;//点的low,dfn值;time从1开始
int node_id;//强连通分量的个数
int head[max_n],s_edge;//邻接表头 s_edge从1开始
int gro_id[max_n];//记录某个点属于哪个强连通分量
int n,m;
int in[max_n],out[max_n];//出度与入度
vector vec[max_n];//边的后节点存储
struct Node
{
int to;
int next;
} edge[max_e];
void init()//初始化
{
s_edge=0;//存储
memset(head,0,sizeof(head));
memset(edge,0,sizeof(edge));
top=0;//tarjian初始化
tim=0;
node_id=0;
memset(isInStack,0,sizeof(isInStack));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(in,0,sizeof(in));//出度入度的初始化
memset(out,0,sizeof(out));
}
void addedge(int u,int v)
{
s_edge++;
edge[s_edge].to=v;
edge[s_edge].next=head[u];
head[u]=s_edge;
}
int min(int a,int b)
{
if(a
Gabow算法代码:
#include
#include
#include
#include
using namespace std;
#define max_n 10005
#define max_e 250002
#define inf 99999999
int stack[max_n],stack1[max_n],top,top1;//栈
int dfn[max_n],tim;//dfn值;time从1开始
int node_id;//强连通分量的个数
int gro_id[max_n];//记录某个点属于哪个强连通分量
int n,m;
int in[max_n],out[max_n];//出度与入度
vector vec[max_n];//边的后节点存储
vector cvec[max_n];//存储每个强连通分量的元素
void init()//初始化
{
top=0;//tarjian初始化
top1=0;
tim=0;
node_id=0;
memset(dfn,-1,sizeof(dfn));
memset(in,0,sizeof(in));//出度入度的初始化
memset(out,0,sizeof(out));
memset(stack,-1,sizeof(stack));
memset(stack1,-1,sizeof(stack1));
memset(gro_id,-1,sizeof(gro_id));
}
void Gabow(int u)
{
stack[++top]=u;
stack1[++top1]=u;//相当于low数组
dfn[u]=tim++; //记录点u出现的记录,并放在栈中
int e,v;
for(e=0; edfn[v])
top1--;
}
}
int j;
if(stack1[top1]==u)//找到一个强连通,元素出栈
{
++node_id;
--top1;
do
{
gro_id[stack[top]]=node_id;
cvec[node_id].push_back(stack[top]);
}while(stack[top--]!=u);
}
}
void find()
{
for(int i = 1 ; i <=n ; ++i)
{
if(dfn[i-1]==-1)
{
Gabow(i-1);
}
}
}
int main()
{
int a,b;
while(scanf("%d %d",&n,&m)!=EOF)
{
init();
for(int i=0; i<=n; i++)
{
vec[i].clear();
cvec[i].clear();
}
for(int i = 0 ; i