关于弧优化
查看原帖
关于弧优化
104624
Yingluosanqian楼主2020/10/4 21:24
#include <bits/stdc++.h>
#define ll long long

using namespace std;

const int MAXN=400050,MAXM=400050;

int n,m,head[MAXN],newhead[MAXN],cnt=1;
int dfn[MAXN],low[MAXN],evis[MAXM*2],cut[MAXM*2],sz[MAXN],clr[MAXN],stk[MAXN],sign[MAXM*2];
int dfncnt=0,clrcnt=0,stkcnt=0;

int ecnt[MAXM*2];

struct EDGE{
	int fr,to,nxt;
}edge[MAXM*2];

void add_edge(int iu,int iv){
	edge[++cnt]=((EDGE){iu,iv,head[iu]});
	newhead[iu]=head[iu]=cnt;
}

void tarjan(int u){
	dfn[u]=low[u]=++dfncnt;
	for(int i=head[u];i;i=edge[i].nxt){
		if(evis[i]==1) continue;
		evis[i]=evis[i^1]=1;
		int v=edge[i].to;
		if(!dfn[v]){
			tarjan(v);
			low[u]=min(low[u],low[v]);
			if(low[v]>dfn[u]){
				cut[i]=cut[i^1]=1;
			}
		}
		else{
			low[u]=min(low[u],dfn[v]);
		}
	}
}

void ebcc(int u){
	if(!clr[u]){
		stk[++stkcnt]=u;
		clr[u]=clrcnt;
	}
	
	for(int &i=newhead[u];i;i=edge[i].nxt){
//		printf("%d!\n",i);
		if(evis[i]||cut[i]){
			continue;
		}
		evis[i]=evis[i^1]=1;
		ebcc(edge[i].to);
	}
	sz[clrcnt]=stkcnt;
}

void dir(int u){
	for(int &i=head[u];i;i=edge[i].nxt){
		int v=edge[i].to;
		if(sign[i]||sign[i^1]) continue;
		sign[i]=1;
		dir(v);
	}
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int inp1,inp2;
		scanf("%d%d",&inp1,&inp2);
		add_edge(inp1,inp2);
		add_edge(inp2,inp1);
	}

	for(int i=1;i<=n;i++){
		if(!dfn[i]){
			tarjan(i);
		}
	}

	memset(evis,0,sizeof evis);
	for(int i=1;i<=n;i++){
		if(!clr[i]){
			++clrcnt;
			stkcnt=0;
			ebcc(i);
		}
	}

	int stt=1;
	for(int i=1;i<=n;i++){
		if(sz[clr[i]]>sz[clr[stt]]){
			stt=i;
		}
	}
	dir(stt);
	
	printf("%d\n",sz[clr[stt]]);
	for(int i=2;i<=2*m+1;i+=2){
		if(sign[i^1]){
			printf("%d %d\n",edge[i].fr,edge[i].to);
		}
		else{
			printf("%d %d\n",edge[i^1].fr,edge[i^1].to);
		}
	}
	
	return 0;
}

这份代码,ebcc函数(用于边双染色)dir(用于定向)中,如果不加弧优化,就去在第四个点TLE。

2020/10/4 21:24
加载中...