80分WA求条
查看原帖
80分WA求条
642173
light_dream楼主2024/9/11 12:16

我的思路是缩点+拓扑排序,先加上 X=1,3,5X=1,3,5 的所有边,然后执行 Tarjan 缩点,一个强连通分量的内部每个小朋友的糖果数量一定全部相等。然后再加入 X=2,4X=2,4 的所有边,走一遍拓扑排序,输出答案。

这是提交记录

有没有哪位大佬可以看看?

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
typedef pair<int,bool> PIB;//pair<node_num,allow_same>
int n,m;
int low[MAXN],dfn[MAXN],tim=0;//dfn[i]表示初次访问i点的时间戳
bool vis[MAXN];
vector<PIB> g[MAXN];
stack<int> st;//访问到某个点u的时候,栈中存储u的祖先和已经访问过的可以到达u的祖先的点
int scc[MAXN];
int cnt[MAXN];
int in_d[MAXN];
int candy[MAXN];
queue<int> q;
int dis[MAXN];
struct EDGE{
	int startpoint;
	int endpoint;
}edge[(MAXN<<3)+(MAXN<<1)];
struct OPERATION{
	int X;
	int u;
	int v;
}qu[MAXN];
void Tarjan(int u){
	low[u]=dfn[u]=++tim;//初次访问
	st.push(u);
	vis[u]=true;
	for(PIB k:g[u]){
		int v=k.first;
		if(dfn[v]==0){//不曾访问
			Tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(vis[v]){
			low[u]=min(low[u],low[v]);
		}
	}
	if(dfn[u]==low[u]){//自成一个强连通分量
		int v;
		do{
			v=st.top();
			st.pop();
			vis[v]=false;
			scc[v]=u;
			++cnt[u];
		}while(u!=v);
	}
}
void Rebuild(){
	for(int i=1;i<=n;++i){
		g[i].clear();
	}
	for(int i=1;i<=m;++i){
		int X=qu[i].X,u=qu[i].u,v=qu[i].v;
		u=scc[u],v=scc[v];
		if(u==v){
			if(X&1){
				
			}
			else{
				putchar('-'),putchar('1');
				exit(0);
			}
		}
		else{
			if(X&1){
				if(X>>2){
					g[u].emplace_back(v,true);
				}
				else if(X>>1){
					g[v].emplace_back(u,true);
				}
				else{
					g[u].emplace_back(v,true);
					g[v].emplace_back(u,true);
				}
			}
			else{
				if(X>>2){
					g[v].emplace_back(u,false);
					++in_d[u];
				}
				else{
					g[u].emplace_back(v,false);
					++in_d[v];
				}
			}
		}
	}
}
long long TP(){
	for(int i=1;i<=n;++i){
		if(i==scc[i]&&in_d[i]==0){
			q.push(i);
			candy[i]=1;
		}
	}
	while(q.size()){
		int u=q.front();
		q.pop();
		if(vis[u]){
			return -1;
		}
		vis[u]=true;
		for(PIB k:g[u]){
			int v=k.first;
			if(--in_d[v]==0){
				q.push(v);
			}
			if(k.second){
				candy[v]=max(candy[v],candy[u]);
			}
			else{
				candy[v]=max(candy[v],candy[u]+1);
			}
		}
	}
	long long ans=0;
	for(int i=1;i<=n;++i){
		if((!vis[i])&&(i==scc[i])){
			return -1;
		}
		if(i==scc[i]){
			ans=ans+(long long)(cnt[i])*(long long)(candy[i]);
		}
	}
	return ans;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1,X,u,v;i<=m;++i){
		scanf("%d%d%d",&X,&u,&v);
		qu[i].u=u;
		qu[i].v=v;
		qu[i].X=X;
		if(X&1){
			if(X>>2){
				g[u].emplace_back(v,true);
			}
			else if(X>>1){
				g[v].emplace_back(u,true);
			}
			else{
				g[u].emplace_back(v,true);
				g[v].emplace_back(u,true);
			}
		}
	}
	for(int i=1;i<=n;++i){
		if(dfn[i]==0){
			Tarjan(i);
		}
	}
	Rebuild();
	printf("%lld",TP());
	return 0;
}
2024/9/11 12:16
加载中...