tarjan萌新求助(关注回报)
查看原帖
tarjan萌新求助(关注回报)
328170
Kalium楼主2021/11/28 14:13

这个代码T了我很疑惑,感觉我没算错复杂度啊

#include <iostream>
#include <cstring>
#include <cstdio>

#define ll long long
#define inf 0x3f3f3f3f

const int N = 1e4 + 7;
const int M = 3e4 + 7;

using namespace std;

int n, m;

int a[N];

struct Edge {
	int to, next;
} edge[M]; 

int head[N], cnt;

int dfn[N], low[N];

int ti;

int stk[N], instk;

bool flag[N];

int num;

int k1[N], k2[N];//k1表示每个环里面的最小权值,k2每个环里表示有多少个最小权值 

int ans1, ans2 = 1;

inline int read() {
	int n = 0, f = 1;
	char c = getchar();
	
	while (c < '0' || c > '9') {
		if (c == '-') f = -f;
		
		c = getchar();
	}
	
	while (c >= '0' && c <= '9') {
		n = (n << 3) + (n << 1) + (c ^ '0');
		c = getchar();
	}
	
	return n * f;
}

inline void addedge(int u, int v) {
	edge[++ cnt] = (Edge) {v, head[u]};
	head[u] = cnt;
}

inline int mina(int a, int b) {
	if (a < b)
		return a;
	return b;
}

void tarjan(int u) {
	dfn[u] = low[u] = ++ ti;
	stk[++ instk] = u;
	flag[u] = 1;
	
	for (int i = head[u]; ~i; i = edge[i].next) {
		int v = edge[i].to;
		
		if (! dfn[v]) {
			tarjan(v);
			low[u] = mina(low[v], low[u]);
		} else if (flag[v])
			low[u] = mina(dfn[v], low[u]);
	}
	
	if (dfn[u] == low[u]) {
		int cur;
		
		num ++;
		
		do {
			cur = stk[instk --];
			flag[cur] = 0;
			
			if (k1[num] == a[cur]) k2[num] ++;
			else {
				k2[num] = 1;
				
				if (k1[num] > a[cur])
					k1[num] = a[cur];
			}
		} while (cur != u);
	}
}

int main() {
	n = read();
	
	for (int i = 1; i <= n; i ++) {
		a[i] = read(); 
		
		k1[i] = inf, head[i] = -1;
	}
	
	m = read();
	
	for (int i = 1; i <= m; i ++) {
		int u, v;
		
		u = read(), v = read();
		
		addedge(u, v);
	}
	
	for (int i = 1; i <= n; i ++)
		if (! dfn[i]) tarjan(i);
	
	/*for (int i = 1; i <= n; i ++)
		cout << belong[i] << " ";*/
	
	for (int i = 1; i <= num; i ++) {
		ans1 += k1[i];
		ans2 *= k2[i];
	}
	
	printf("%d %d\n", ans1, ans2);
	
	return 0;
} 
2021/11/28 14:13
加载中...