社区讨论

求大神指点区别

P2341[USACO03FALL / HAOI2006] 受欢迎的牛 G参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mi6u32r9
此快照首次捕获于
2025/11/20 10:50
4 个月前
此快照最后确认于
2025/11/20 10:50
4 个月前
查看原帖
同一份代码
tarjan后找出度为零的连通分量
两种输出处理求区别
注释起来的是65分(没有剩余部分)
注释后面到代码结束是100分
CPP
#include<cstdio>
#include<stack>
#include<queue>
#include<memory.h>
#define MAXN 10005
#define MAXM 50005
using namespace std;
int head[MAXN];
int next[MAXM];
int COL[MAXN];
int DFN[MAXN];
int LOW[MAXN];
int CNT[MAXN];
int OUTD[MAXN];
int tm=0,id=0,n,m,tot;
stack<int> S;
bool V[MAXN];
struct edge
{
	int x,y;
} E[MAXM];
void init()
{
	memset(head,0,sizeof(head));
	memset(next,0,sizeof(next));
	memset(OUTD,0,sizeof(OUTD));
	id=0;
}
void ADD(int a,int b)
{
	id++;
	E[id].x=a;
	E[id].y=b;
	OUTD[a]++;
	next[id]=head[a];
	head[a]=id;
}
void SCAN()
{
	int i;
	scanf("%d %d",&n,&m);
	for(i=1; i<=m; i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);
		ADD(a,b);
	}
}
void TJ(int x)
{
	DFN[x]=LOW[x]=++tm;
	V[x]=1;
	S.push(x);
	int i;
	for(i=head[x]; i; i=next[i])
	{
		int y=E[i].y;
		if(!DFN[y])
		{
			TJ(y);
			LOW[x]=min(LOW[x],LOW[y]);
		}
		else if(V[y])
			LOW[x]=min(LOW[x],LOW[y]);
	}
	if(LOW[x]==DFN[x])
	{
		int y=0;
		tot++;
		while(x!=y)
		{
			y=S.top();
			S.pop();
			V[y]=0;
			COL[y]=tot;
			CNT[tot]++;
		}
	}
}
void MKMP()
{
	int i;
	for(i=1; i<=m; i++)
	{
		int x=E[i].x,y=E[i].y;
		if(COL[x]!=COL[y])
			OUTD[COL[x]]++;
	}
	n=tot;
}
int main()
{
	SCAN();
	int i;
	for(i=1; i<=n; i++)
		if(!DFN[i])
			TJ(i);
	init();
	MKMP();
	/*int ans;
	bool flag=0;
	for(i=1; i<=n; i++)
		if(!OUTD[i])
		{
			if(!flag)
			{
				ans=CNT[i];
				flag=1;
			}
			else
			{
				printf("0");
				return 0;
			}
		}
	printf("%d",ans);
	return 0;*/
	int tt=0;
	for(int i=1; i<=n; i++)
		if(!OUTD[i])
		{
			if(tt)
			{
				printf("0");
				return 0;
			}
			tt=i;
		}
	printf("%d",CNT[tt]);
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...