[BZOJ4086][Sdoi2015]travel && 暴力

本文详细解析了K值从2到7的吐血膜富爷题解,包括初始化、边添加、工作函数等关键步骤,通过C++实现并附上代码实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分别讨论K=2到K=7 吐血 膜富爷的题解

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>
#define SF scanf
#define PF printf
using namespace std;
typedef long long LL;
inline 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*10+ch-'0'; ch=getchar(); }
	return x*f;
}
const int MAXN = 1000;
const int MAXM = 5000;
struct Node {
	int v, next;
} Edge[MAXM*2+10];
int adj[MAXN+10], ecnt;
void addedge(int u, int v) {
	Node &e = Edge[++ecnt];
	e.v = v; e.next = adj[u]; adj[u] = ecnt;
}
int n, m, K;
void init() {
	memset(adj, 0, sizeof(adj));
	ecnt = 0;
}
int vis[MAXN+10], pai[MAXN+10][MAXN+10];
bool ok[MAXN+10][MAXN+10], G[MAXN+10][MAXN+10];
void work2() {
	for(int u = 1; u <= n; u++)
		for(int i = adj[u]; i; i = Edge[i].next)
			ok[u][Edge[i].v] = true;
}
void work3() {
	for(int u = 1; u <= n; u++)
		for(int i = adj[u]; i; i = Edge[i].next)
			for(int j = adj[u]; j; j = Edge[j].next) {
				int v1 = Edge[i].v, v2 = Edge[j].v;
				if(v1 != v2) ok[v1][v2] = true;
			}
}
void work4() {
	for(int u = 1; u <= n; u++)
		for(int v = u+1; v <= n; v++) {
			if(u == v) continue;
			int x, y;
			for(int i = adj[u]; i; i = Edge[i].next) {
				for(int j = adj[v]; j; j = Edge[j].next) {
					x = Edge[i].v; y = Edge[j].v;
					if(G[x][y] && x != y && x != v && y != u ) {
						ok[v][u] = ok[u][v] = true;
						break;
					}
				}
				if(ok[u][v]) break;
			}
		}
}
void work5() {
	for(int u = 1; u <= n; u++)
		for(int v = u+1; v <= n; v++) {
			int tot = 0;
			for(int i = adj[u]; i; i = Edge[i].next) {
				int x = Edge[i].v;
				if(G[x][v]) {
					vis[x] = 1;
					tot++;
				}
			}
			for(int i = adj[u]; i; i = Edge[i].next) 
				for(int j = adj[v]; j; j = Edge[j].next) {
					int x = Edge[i].v, y = Edge[j].v;
					if(x == y || x == v || y == u) continue;
					if(tot - vis[x] - vis[y] > 0) 
						ok[x][y] = ok[y][x] = true;
				}
			for(int i = adj[u]; i; i = Edge[i].next) vis[Edge[i].v] = 0;
		}
}
void work6() {
	for(int u = 1; u <= n; u++)
		for(int v = u+1; v <= n; v++) {
			int tot = 0;
			for(int i = adj[u]; i; i = Edge[i].next) 
				for(int j = adj[v]; j; j = Edge[j].next) {
					int x = Edge[i].v, y = Edge[j].v;
					if(x == y || x == v || y == u) continue;
					if(G[x][y]) {
						tot++;
						vis[x]++; vis[y]++; 
					}
				}
			for(int i = adj[u]; i; i = Edge[i].next) 
				for(int j = adj[v]; j; j = Edge[j].next) {
					int x = Edge[i].v, y = Edge[j].v;
					if(x == y || x == v || y == u) continue;
					if(tot - vis[x] - vis[y] + (G[x][y] ? 1 : 0) > 0)
						ok[x][y] = ok[y][x] = true;
				}
			for(int i = adj[u]; i; i = Edge[i].next) vis[Edge[i].v] = 0;
			for(int i = adj[v]; i; i = Edge[i].next) vis[Edge[i].v] = 0;
		}
}
vector <int> M[MAXN+1][MAXN+1];
int exist[MAXN+1][MAXN+1], middle[MAXN+1], C[MAXN+1];
int Q[MAXN+10], top, Vis[MAXN+1][MAXN+1], Time;
int QQ[MAXN+10], top1, QQQ[MAXN*MAXN+10][2], top2;
void work7() {
	for(int i = 1; i <= n; i++)
		for(int j = i+1; j <= n; j++)
			M[i][j].clear();
	for(int u = 1; u <= n; u++) {
		top = 0;
		for(int i = adj[u]; i; i = Edge[i].next) Q[++top] = Edge[i].v;
		for(int i = 1; i <= top; i++)
			for(int j = i+1; j <= top; j++) {
				int x = Q[i], y = Q[j];
				if(x > y) swap(x, y);
				M[x][y].push_back(u);
			}
	}
	for(int u = 1; u <= n; u++) {
		for(int v = u+1; v <= n; v++) {
			int tot = 0;
			top1 = top2 = 0;
			Time++;
			for(int i = adj[u]; i; i = Edge[i].next)
				for(int j = adj[v]; j; j = Edge[j].next) {
					int x = Edge[i].v, y = Edge[j].v;
					if(x == v || x == y || y == u) continue;
					if(x > y) swap(x, y);
					if(Vis[x][y] != Time) Vis[x][y] = Time, pai[x][y] = 0;
					for(int k = 0; k < M[x][y].size(); k++) {
						int mid = M[x][y][k];
						if(mid == u || mid == v) { pai[x][y]++; continue; }
						exist[mid][x]++; exist[mid][y]++;
						if(!middle[mid]) QQ[++top1] = mid;
						middle[mid]++;
						QQQ[++top2][0] = mid; QQQ[top2][1] = x;
						QQQ[++top2][0] = mid; QQQ[top2][1] = y;
						C[x]++; C[y]++;
						tot++;
					}
				}
			for(int i = adj[u]; i; i = Edge[i].next)
				for(int j = adj[v]; j; j = Edge[j].next) {
					int x = Edge[i].v, y = Edge[j].v;
					if(x == v || x == y || y == u) continue;
					if(x > y) swap(x, y);
					int del = tot - C[x] - C[y] - middle[x] - middle[y] + exist[x][y] + exist[y][x] + (M[x][y].size() - pai[x][y]);
					if(del > 0)
						ok[x][y] = ok[y][x] = true;
				}
			for(int i = adj[u]; i; i = Edge[i].next) C[Edge[i].v] = 0;
			for(int i = adj[v]; i; i = Edge[i].next) C[Edge[i].v] = 0;
			for(int i = 1; i <= top1; i++) middle[QQ[i]] = 0;
			for(int i = 1; i <= top2; i++) 
				exist[QQQ[i][0]][QQQ[i][1]] = 0;
		}
	}
}
int main() {
	int _T = read(); while(_T--) {
		init();
		memset(G, 0, sizeof(G));
		memset(ok, 0, sizeof(ok));
		n = read(); m = read(); K = read();
		while(m--) {
			int u = read(), v = read();
			if(u == v) continue;
			addedge(u,v); addedge(v,u);
			G[u][v] = G[v][u] = true;
		}
		if(K == 2) work2();
		else if(K == 3) work3();
		else if(K == 4) work4();
		else if(K == 5) work5();
		else if(K == 6) work6();
		else work7();
		for(int i = 1; i <= n; i++) {
			for(int j = 1; j <= n; j++)
				putchar(ok[i][j] ? 'Y' : 'N');
			puts("");
		}
	}
}
/*
1
10 12 7
1 2
2 3
3 5
1 4
4 5
2 5
5 6
6 7
7 8
8 9
9 10
10 3
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值