图论

边双

int n,m;
int head[maxn],tot=1;
struct nd{
	int nxt,to;
}e[maxn<<1];
void add(int u,int v){e[++tot]={head[u],v};head[u]=tot;}
int dfn[maxn],lw[maxn],idx;
int st[maxn],tp;
vector<int> g[maxn];
int num;
bool vis[maxn];
void tar(int u,int fl){
	dfn[u]=lw[u]=++idx;st[++tp]=u;
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(i==(fl^1))continue;
		if(!dfn[v]){
			tar(v,i);
			lw[u]=min(lw[u],lw[v]);
		}
		else lw[u]=min(lw[u],dfn[v]);
	}
	if(lw[u]==dfn[u]){
		++num;
		g[num].push_back(st[tp]);
		while(st[tp--]!=u){
			g[num].push_back(st[tp]);
		}
	}
}
void work(){
	n=read();m=read();
	for(int i=1;i<=m;i++){
		int u=read(),v=read();
		add(u,v),add(v,u);
	}
	for(int i=1;i<=n;i++)if(!dfn[i])tar(i,0);
	printf("%lld\n",num);
	for(int i=1;i<=num;i++){
		printf("%lld ",g[i].size());
		for(int j:g[i])printf("%lld ",j);
		printf("\n");
	}
}

点双

int n,m,num;
vector<int> e[maxn],g[maxn];
int dfn[maxn],idx,lw[maxn];
int st[maxn],tp;
void tar(int u){
	dfn[u]=lw[u]=++idx;st[++tp]=u;
	for(int v:e[u]){
		if(!dfn[v]){
			tar(v);
			lw[u]=min(lw[u],lw[v]);
			if(lw[v]>=dfn[u]){
				g[++num].push_back(st[tp]);
				while(st[tp--]!=v)g[num].push_back(st[tp]);
				g[num].push_back(u);
			}
		}
		else lw[u]=min(lw[u],dfn[v]);
	}
}
void work(){
	n=read();m=read();
	for(int i=1;i<=m;i++){
		int u=read(),v=read();
		e[u].push_back(v),e[v].push_back(u);
	}
	for(int i=1;i<=n;i++)if(!dfn[i]){
		int lst=idx;tar(i);
		if(idx==lst+1)g[++num].push_back(i);
	}
	printf("%lld\n",num);
	for(int i=1;i<=num;i++){
		printf("%lld ",(int)g[i].size());
		for(int j:g[i])printf("%lld ",j);printf("\n");
	}
}

无向图四元环计数

int n,m;
int d[maxn],cnt[maxn],ans;
vector<int> e[maxn],g[maxn];
void work(){
	n=read();m=read();
	for(int i=1;i<=m;i++){
		int u=read(),v=read();
		e[u].push_back(v),e[v].push_back(u);
		d[u]++,d[v]++;
	}
	for(int u=1;u<=n;u++){
		for(int v:e[u])if(d[u]>d[v]||(d[u]==d[v]&&u>v))g[u].push_back(v);
	}
	for(int i=1;i<=n;i++){
		for(int j:g[i]){
			for(int k:e[j])if(d[i]>d[k]||(d[i]==d[k]&&i>k))ans+=cnt[k]++;
		}
		for(int j:g[i])for(int k:e[j])cnt[k]=0;
	}
	printf("%lld\n",ans);
}