一个疑问
查看原帖
一个疑问
550074
cloudemakers楼主2023/6/20 15:07

#98 pts Code:

#include<bits/stdc++.h>
#define ll long long
#define maxn 200050
#define maxm 600050
using namespace std;
int n,m,low[maxn],st[maxn],top,cnt2,siz[maxn],siz2[maxn],siztot;
int dfn[maxn],idx,root;
ll ans;
int read(){
	int x=0,f=1;
	char ch=getchar();
	while (ch<'0'||ch>'9'){
		if (ch=='-') f=-1;
		ch=getchar();
	}
	while (ch>='0'&&ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*f;
}
struct E{
	int cnt,to[maxm],nxt[maxm],head[maxn];
	void addedge(int a,int b){
		to[cnt]=b;nxt[cnt]=head[a];head[a]=cnt++;
		to[cnt]=a;nxt[cnt]=head[b];head[b]=cnt++;
	}
}F,S;
void tarjang(int now,int f){
	dfn[now]=++cnt2;low[now]=dfn[now];
	st[++top]=now;siztot++;siz[now]=-1;
	for (int i=F.head[now];i;i=F.nxt[i]){
		int v=F.to[i];
		if (i==(f^1)) continue;
		if (!dfn[v]){
			tarjang(v,i);
			low[now]=min(low[now],low[v]);
			if (low[v]>=dfn[now]){
				int vv;idx++;
				while (vv!=v){
					vv=st[top--];
					S.addedge(vv,idx+n);
					siz[idx+n]++;
				}
				S.addedge(now,idx+n);
				siz[idx+n]++;
			}
		}
		else low[now]=min(low[now],dfn[v]);
	}//build tree
}
void dfs(int now,int fa){
	if (now<=n) siz2[now]++;
	ll add=0;
	for (int i=S.head[now];i;i=S.nxt[i]){
		int v=S.to[i];
		if (v==fa) continue;
		dfs(v,now);
		add+=(1ll*siz2[now]*siz2[v]);
		siz2[now]+=siz2[v];
	}
	add+=(1ll*siz2[now]*(siztot-siz2[now]));
	add<<=1;
	ans+=(1ll*add*siz[now]);
}
void print(){
	cout<<"||||";
	for (int i=1;i<=n;i++)	
		cout<<low[i]<<" ";
	cout<<endl;
} 
int main(){
	n=read();m=read();
	F.cnt=2;S.cnt=2;
	for (int i=1,u,v;i<=m;i++){
		u=read();v=read();
		F.addedge(u,v);
	}
	for (int i=1;i<=n;i++){
		if (!dfn[i]){
			root=i;
			top=0;siztot=0;
			tarjang(i,-1);
			dfs(i,-1);
		}
	}
	printf("%lld",ans);
	return 0;
}

在tarjang算法中把f参数去掉就可以AC 为什么?不用保证不去走刚刚走过的边吗?

2023/6/20 15:07
加载中...