求助 tarjan
查看原帖
求助 tarjan
420102
phmaprostrate楼主2021/10/30 18:47

一个点 ReRe 一个点 WaWa.

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 5e5 + 10;
const int M = 2e6 + 10;
int n,m,p,total;
struct node {
	int to,next;
	bool operator < (const node aa)const {
		return to < aa.to;
	}
} tr[2 * M];
struct node2{
	int from,to;
}ne[N];
set<node> pp;
int h[N],k = 0;
int dfn[N],low[N],num = 0;
int s[N],ins[N],top = 0,cnt = 0;
int siz[N],id[N];
int from[N],to[N];
int dp[N],e[N];
int d[N],in[N],cnt2 = 0,idd;
queue<int> q;
bool cmp(node2 aa,node2 bb){
	if(aa.from != bb.from) return aa.from < bb.from;
	else return aa.to < bb.to;
}
void add(int from,int to) {
	tr[++k].to = to;
	tr[k].next = h[from];
	h[from] = k;
}
void tarjan(int x) {
	dfn[x] = low[x] = ++num;
	s[++top] = x,ins[x] = true;
	for(int i = h[x] ; i ; i = tr[i].next) {
		int y = tr[i].to;
		if(!dfn[y]) {
			tarjan(y);
			low[x] = min(low[x],low[y]);
		} else if(ins[y]) low[x] = min(low[x],dfn[y]);
	}
	if(low[x] == dfn[x]) {
		int z;
		cnt ++;
		do {
			z = s[top--];
			id[z] = cnt;
			siz[cnt] ++;
			ins[z] = false;
		} while(z != x);
	}
}
void init() {
	memset(tr,0,sizeof(tr));
	k = 0;
	memset(h,0,sizeof(h));
}
void check(int u,int v) {
	if(dp[v] < dp[u] + siz[v]) {
		dp[v] = dp[u] + siz[v];
		e[v] = 0;
		if(dp[idd] < dp[v]) idd = v;
	}
	if(dp[v] == dp[u] + siz[v])
		e[v] = (e[v] + e[u]) % p;
}
void rever(){
	sort(ne + 1,ne + 1 + k,cmp);
	for(int i = 1 ; i <= k ; i ++){
		if(ne[i].from == ne[i - 1].from && ne[i].to == ne[i - 1].to) continue;
		add(ne[i].from,ne[i].to);
		in[ne[i].to] ++;
	}
}
void tuopu() {
	for(int i = 1 ; i <= cnt ; i ++) if(!in[i]) q.push(i),dp[i] = siz[i],e[i] = 1;
	for(int i = 1 ; i <= cnt ; i ++) if(dp[idd] < dp[i]) idd = i;
	while(!q.empty()) {
		int u = q.front();
		q.pop();
		d[++cnt2] = u;
		for(int i = h[u] ; i ; i = tr[i].next) {
			int y = tr[i].to;
			in[y] --;
			check(u,y);
			if(!in[y]) q.push(y);
		}
	}
}
signed main() {
	cin >> n >> m >> p;
	for(int i = 1 ; i <= m ; i ++) {
		cin >> from[i] >> to[i];
		add(from[i],to[i]);
	}
	for(int i = 1 ; i <= n ; i ++)
		if(!dfn[i]) tarjan(i);
	init();
	for(int i = 1 ; i <= m ; i ++) {
		int a = id[from[i]],b = id[to[i]];
		if(a != b) {
	     ne[++k].from = a;
	     ne[k].to = b;
		}
	}
	rever();
	tuopu();
	
	for(int i = 1 ; i <= cnt ; i ++) {
		if(dp[i] == dp[idd])
			total = (total + e[i]) % p;
		//if(dp[i] > dp[idd]) idd = i,total = e[i];
	//	else if(dp[i] == dp[idd]) total += e[i],total %= p;
	}
	cout << dp[idd] <<endl << total;
	return 0;
}
2021/10/30 18:47
加载中...