AcWing 4979. 合适的环(AcWing杯 - 周赛)(有技巧的枚举)

思路:

我们枚举边,因为我们只需要三个点组成的环,然而我们一条边就可以确实两个点(该边的左右端点),然后我们只需再枚举最后一个点(第三个点),即可达到第一步要求。

然后判断这三个点是否能直接成环(不依赖其他点,边,因为一旦引入其他点辅助,那必然该环不只是三个点,不符合题意,所以我们可以用邻接矩阵来在输入时候简单标记二者直接的关系(是否可以直接到达))

然后就x怎么求呢,每次都暴力一次肯定是不妥的,会T,那我们确其实只需要预处理一遍,把所有点的度数求出来,然后当前环的X就等于三个点的度数再减去三个点相连的边(-3*2,因为在计算度数的时候这三条边,每条都被计算了两次)

okk,那这样子一份香喷喷的ACcode就出炉啦~

ACcode(安全食用):(喜欢就给UP点个赞呗~,激发动力给大家带来更优秀的文章~)


#include
using namespace std;
#define int long long
const int N=4e3+10;
int n,m,d[N];
bool  mp[N][N];
struct E {
	int a,b;//边的两个点 
} e[N];//边 
void solve() {
	cin>>n>>m;
	for(int i=1; i<=m; i++) {
		cin>>e[i].a>>e[i].b;
		mp[e[i].a][e[i].b]=	mp[e[i].b][e[i].a]=true; 
		d[e[i].a]++,d[e[i].b]++;//度数 
	}
	int ans=-1;//结果 
	for(int i=1; i<=m; i++) { //枚举边
		int a=e[i].a,b=e[i].b;
		for(int j=1; j<=n; j++) { //已经有了上面的一边的两个点 
			//只需再一点,所以我们枚举另一个点 
			if(mp[a][j]&&mp[b][j]) {
				int cnt=d[a]+d[b]+d[j]-6;//x 
				if(ans==-1||cnt>tt;
	while(tt--) solve();
	return 0;
}
//3


over~

你可能感兴趣的:(算法,模拟,思维)