求问这题如何用分层图做
查看原帖
求问这题如何用分层图做
928972
ny_Dacong楼主2025/1/21 08:57

rt,复制一层图,然后在两层图中间连原图的反向边,表示一次逆行。

然而我发现边权不好搞。因为你分层之后可能会有点重复贡献。所以怎么去重?

以为我 SPFA 假了,调了好久,现在发现这个问题之后大脑直接宕机了。求大佬调。

#include<bits/stdc++.h>
using namespace std;
int n,m;
vector<int> org[100050];
stack<int> que;
bitset<100050> inque;
int dtot = 0,stot = 0,dfn[100050],low[100050],id[100050];
int Size[100050];
void tarjan(int now){
	dfn[now] = low[now] = ++dtot;
	que.push(now);
	inque[now] = 1;
	for(auto i:org[now]){
		if(!dfn[i]){
			tarjan(i);
			low[now] = min(low[now],low[i]);
		}else if(inque[i]){
			low[now] = min(low[now],dfn[i]);
		}
	}
	if(dfn[now] == low[now]){
		int y;
		stot++;
		do{
			y = que.top();
			que.pop();
			inque[y] = 0;
			id[y] = stot;
			Size[stot]++;
		}while(y != now);
	}
	return;
}
int etot = 0,Last[200050],Next[300050],End[300050];
void addedge(int u,int v){
//	printf("!%d %d\n",u,v);
	etot++;
	Next[etot] = Last[u];
	Last[u] = etot;
	End[etot] = v;
	return;
}
namespace spfa{
	int dis[200050];
	bitset<200050> inque;
	queue<int> que;
	void spfa(){
		memset(dis,-0x3f,sizeof(int)*((stot<<1)+10));
		inque.reset();
		while(que.size()){
			que.pop();
		}
		dis[id[1]] = Size[id[1]];
		que.push(id[1]);
		inque[id[1]] = 1;
		int now;
		while(que.size()){
			now = que.front();
			que.pop();
			inque[now] = 0;
			for(int i = Last[now]; i; i = Next[i]){
				if(dis[End[i]] < dis[now]+Size[End[i]]){
					dis[End[i]] = dis[now]+Size[End[i]];
					if(inque[End[i]]){
						continue;
					}
					que.push(End[i]);
					inque[End[i]] = 1;
				}
			}
		}
		return;
	}
}
using spfa::dis;
int main(){
	scanf("%d%d",&n,&m);
	while(m--){
		static int tpa,tpb;
		scanf("%d%d",&tpa,&tpb);
		org[tpa].push_back(tpb);
	}
	for(int i = 1; i <= n; i++){
		if(!dfn[i]){
			tarjan(i);
		}
	}
	for(int i = 1; i <= stot; i++){
		Size[i+stot] = Size[i];
	}
	for(int i = 1; i <= n; i++){
		for(auto j:org[i]){
			if(id[i] != id[j]){
				addedge(id[i],id[j]);
				addedge(id[i]+stot,id[j]+stot);
				addedge(id[j],id[i]+stot);
			}
		}
	}
	if(stot == 1){
		printf("%d",Size[1]);
		return 0;
	}
	spfa::spfa();
	printf("%d",max(dis[id[1]+stot],dis[id[1]]));
	return 0;
}
2025/1/21 08:57
加载中...