为什么-1挂了
查看原帖
为什么-1挂了
753068
EchoHua0402楼主2024/3/31 20:44

80pts代码如下:

评测记录

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,k;
struct edge{int v,w;};
vector<edge> G1[N],G2[N];
int low[N],dfn[N],scc[N],siz[N],dfscnt=0,scccnt=0;
bool inst[N];
stack<int> s;
int in[N];
void Tarjan(int u)
{
	low[u]=dfn[u]=++dfscnt;
	inst[u]=1;
	s.push(u);
	for (edge e:G1[u])
	{
		int v=e.v,w=e.w;
		if (w==1) continue;
		if (!dfn[v])
		{
			Tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if (inst[v]) low[u]=min(low[u],dfn[v]);
	}
	if (dfn[u]==low[u])
	{
		scccnt++;
		while (s.top()!=u)
		{
			int node=s.top();
			inst[node]=0;
			scc[node]=scccnt;
			s.pop();
			siz[scccnt]++;
		}
		s.pop();
		scc[u]=scccnt;
		inst[u]=0;
		siz[scccnt]++;
	}
}
void build()
{
	for (int u=1;u<=n;u++)
	{
		for (edge e:G1[u])
		{
			int v=e.v,w=e.w;
			if (scc[u]!=scc[v])
			{
				G2[scc[u]].push_back({scc[v],w});
				in[scc[v]]++;
			}
		}
	}
}
queue<int> q;
int dp[N];
bool vis[N],flg=1;
void Topo()
{
	memset(dp,0,sizeof(dp));
	memset(vis,0,sizeof(vis));
	for (int i=1;i<=scccnt;i++)
	{
		if (in[i]==0)
		{
			dp[i]=1;
			q.push(i);
		}
	}
	int cnt=0;
	while (!q.empty())
	{
		int u=q.front();
		q.pop();
		vis[u]=1;
		cnt++;
		for (edge e:G2[u])
		{
			int v=e.v,w=e.w;
			in[v]--;
			dp[v]=max(dp[v],dp[u]+w);
			if (!in[v]&&(!vis[v])) q.push(v);
		}
	}
	if (cnt<scccnt) flg=0;
}
int main()
{
	scanf("%d%d",&n,&k);
	int u,v,w;
	for (int i=1;i<=k;i++)
	{
		scanf("%d%d%d",&w,&u,&v);
		if (w==1)
		{
			G1[u].push_back({v,0});
			G1[v].push_back({u,0});
		}
		if (w==2) G1[u].push_back({v,1});
		if (w==3) G1[v].push_back({u,0});
		if (w==4) G1[v].push_back({u,1});
		if (w==5) G1[u].push_back({v,0});
	}
	for (int i=1;i<=n;i++)
	{
		if (!dfn[i]) Tarjan(i);
	}
	build();
	Topo();
	if (!flg) cout<<-1<<endl;
	else
	{
		long long ans=0;
		for (int i=1;i<=scccnt;i++)	ans+=((long long)dp[i]*siz[i]);
		printf("%lld\n",ans);
	}
	return 0;
}

AC代码如下:

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,k;
struct edge{int v,w;};
vector<edge> G1[N],G2[N];
int low[N],dfn[N],scc[N],siz[N],dfscnt=0,scccnt=0;
bool inst[N];
stack<int> s;
int in[N];
void Tarjan(int u)
{
	low[u]=dfn[u]=++dfscnt;
	inst[u]=1;
	s.push(u);
	for (edge e:G1[u])
	{
		int v=e.v;
		if (!dfn[v])
		{
			Tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if (inst[v]) low[u]=min(low[u],dfn[v]);
	}
	if (dfn[u]==low[u])
	{
		scccnt++;
		while (s.top()!=u)
		{
			int node=s.top();
			inst[node]=0;
			scc[node]=scccnt;
			s.pop();
			siz[scccnt]++;
		}
		s.pop();
		scc[u]=scccnt;
		inst[u]=0;
		siz[scccnt]++;
	}
}
bool flg=1;
void build()
{
	for (int u=1;u<=n;u++)
	{
		for (edge e:G1[u])
		{
			int v=e.v,w=e.w;
			if (scc[u]==scc[v]&&w==1)
			{
				flg=0;
				return ;
			}
			if (scc[u]!=scc[v])
			{
				G2[scc[u]].push_back({scc[v],w});
				in[scc[v]]++;
			}
		}
	}
}
queue<int> q;
int dp[N];
void Topo()
{
	memset(dp,0,sizeof(dp));
	for (int i=1;i<=scccnt;i++)
	{
		if (in[i]==0)
		{
			dp[i]=1;
			q.push(i);
		}
	}
	while (!q.empty())
	{
		int u=q.front();
		q.pop();
		for (edge e:G2[u])
		{
			int v=e.v,w=e.w;
			in[v]--;
			dp[v]=max(dp[v],dp[u]+w);
			if (!in[v]) q.push(v);
		}
	}
}
int main()
{
	scanf("%d%d",&n,&k);
	int u,v,w;
	for (int i=1;i<=k;i++)
	{
		scanf("%d%d%d",&w,&u,&v);
		if (w==1)
		{
			G1[u].push_back({v,0});
			G1[v].push_back({u,0});
		}
		if (w==2) G1[u].push_back({v,1});
		if (w==3) G1[v].push_back({u,0});
		if (w==4) G1[v].push_back({u,1});
		if (w==5) G1[u].push_back({v,0});
	}
	for (int i=1;i<=n;i++)
	{
		if (!dfn[i]) Tarjan(i);
	}
	build();
	if (!flg)
	{
		printf("-1\n");
		return 0;
	}
	Topo();
	long long ans=0;
	for (int i=1;i<=scccnt;i++)	ans+=((long long)dp[i]*siz[i]);
	printf("%lld\n",ans);
	return 0;
}

感觉本质上是一样的,但为什么第一份代码判-1挂了。

拜谢。

2024/3/31 20:44
加载中...