QBXT T15565 Day4上午道路分组

有向并查集维护连通性
优化:
vis数组表示能被节点1到达的点
显然,已经分在一个联通块中的点就没必要在用该点扩展了。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int maxn = 311010;
vector<int>s[maxn];
inline int read() {
	int x=0,f=1;
	char c=getchar();
	while (c<'0'||c>'9') {
		if(c=='-') f=1;
		c=getchar();
	}
	while (c<='9'&&c>='0') {
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}
int n,m;
struct node{
	int x,y;
}edge[2*maxn];
bool vis[maxn];
int f[maxn];
int dfs(int x) {
	int ret=0;
	if(x==n) ret=-1;
	vis[x]=1;
	int siz=s[x].size();
	for(int i=0;i<siz;i++) {
		int y=s[x][i];
		if(vis[y]==1)
			continue;
		if(dfs(y)==-1)
			ret=-1;
	}
	return ret;
}
int main() {
	n=read(),m=read();
	for(int i=1;i<=m;++i) {
		edge[i].x=read();
		edge[i].y=read();
	}
	int ans=0,cnt=0;
	for(int i=1;i<=m;++i) {
		int x=edge[i].x,y=edge[i].y;
		s[x].push_back(y);
		f[++cnt]=x;
		f[++cnt]=y;
		vis[1]=1;
		if(vis[x]) {
			int tmp=dfs(y);
			if(tmp==-1) {
				ans++;
				for(int j=1;j<=cnt;++j) {
					vis[f[j]]=0;
					s[f[j]].clear();
				}
				i--;
				cnt=0;
			}
		}
	}
	printf("%d
",ans+1);
	return 0;
}
原文地址:https://www.cnblogs.com/sssy/p/7792110.html