为什么洛谷AC SPOJ却RE
查看原帖
为什么洛谷AC SPOJ却RE
759274
Stevehim楼主2023/7/10 21:33
#include <bits/stdc++.h>
#define maxn 500010
#define MAX(a,b,c) max(max(a,b),max(b,c))
using namespace std;
int cnt,tot,tim;
int belong[maxn];
int dfn[maxn];
int low[maxn];
bool gedian[maxn];
int not_ge_cnt;
int ge_cnt;
int rt,rt_po; //根节点和根节点子节点数
struct edge{
	int to,nxt;
}e[maxn];
int head[maxn];
void add(int x,int y){
	e[++cnt].to = y;
	e[cnt].nxt = head[x];
	head[x] = cnt;
}
void tarjan(int x,int fa){ //tarjan求割点
	dfn[x] = low[x] = ++tim;
	for(int i = head[x];i; i = e[i].nxt){
		int u = e[i].to;
		if(!dfn[u]){
			tarjan(u,x);
			low[x] = min(low[x],low[u]);
			if(low[u] >= dfn[x]){
				if(x != rt) gedian[x] = true;
				else rt_po++;
			}
		}else{
			if(u != fa){
				low[x] = min(low[x],dfn[u]);
			}
		}
	}
}
//bool vis[maxn] = {false};/
void dfs(int x){ //dfs搜连通块
	belong[x] = tot;
	not_ge_cnt++;
	if(gedian[x]) return;
	for(int i = head[x];i;i = e[i].nxt){
		int u = e[i].to;
		if(gedian[u] && belong[u] != tot){ //是割点并且不在这个连通分量
			ge_cnt++;
			belong[u] = tot;
		}
		if(!belong[u]){
			dfs(u); //判断割点和看dfs是不关联的,并不放在一个if里
		}
	}
}
int u,v;
int m,n;
int Case = 1;
long long ans1,ans2;
void init(){
	memset(head,0,sizeof head);
	memset(dfn,0,sizeof dfn);
	memset(low,0,sizeof low);
	memset(gedian,false,sizeof gedian);
	memset(belong,0,sizeof belong);
	tim =  tot = n = ans1 = 0;
//	cnt = 0;
	ans2 = 1; //乘法,不能设0
}
int main(){
//	ios::sync_with_stdio(false);
	while(1){
		init();
		cin >> m;
		if(m == 0) break;
		for(int i = 1; i <= m; i++){
			cin >> u >> v;
			add(u,v),add(v,u); //双向建边
			n = MAX(n,u,v); //因为题中没给n,得比较出来
		}
		for(int i = 1; i <= n; i++){
			if(!dfn[i]){
				rt = i;
				rt_po = 0;
				tarjan(rt,0);
				if(rt_po >= 2) gedian[i] = true; //割点的特殊判定:作为根节点如果子节点个数超过1则是割点
			}
		}
		for(int i = 1; i <= n; i++){
			if(!gedian[i] && !belong[i]){
				++tot;
				ge_cnt = not_ge_cnt = 0;
				dfs(i);
				if(ge_cnt == 0){
					ans1 += 2;
					ans2 *= ((not_ge_cnt - 1) * not_ge_cnt) / 2; //组合数我记得,从n个任意非割点的地方选两个
				}
				if(ge_cnt == 1){
					ans1 += 1;
					ans2 *= not_ge_cnt;
				}
				
			}
		}
		printf("Case %d: %lld %lld\n",Case++,ans1,ans2);
	}
	return 0;
}
2023/7/10 21:33
加载中...