环形划分
题目大意:你有一个 n 个点的完全图,现在你要从中选取若干个三元环,使得这些三元环两两没有重边,并且使得不在三元环中的边数 ≤ n − 1。请给出一种方案或者指出无解。
Sample Input
4
Sample Output
Yes
1
1 2 3
Hint
一个图如果不存在 k 染色,那么一定存在一个长度大于 k 且模 k 为 1的环。
例如一个图如果不能二染色,一定存在奇环。
题解:
首先这个Hint一点都没用!!!!!!!!!!!
显然我们随便画一个完全图,一定存在一个三元环。。。
好的正式分析,这道题是一道构造题,也就是说直接想是不行的,要构造一些特殊的符合题意的情况,那么对于一个三元环(i,j,k)(设i <j<k),只要满足(i + j + k) % n == 0就行。
显然对于一对不同的i, j,仅有唯一的k 满足上述条件,所以该构造不存在环与环之间的重边。
不合法的情况仅有当k与i或j相等时,相当于i,j之间的边没有被选,则没被选的边的个数为n-1,符合条件。
因此枚举即可。显然根本不存在无解的情况。
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<vector> #include<iostream> #include<ctime> #include<cstdlib> #define B printf("Break\n"); #define A(x) cout << #x << " " << (x) << endl; #define ll long long using namespace std; void file() { freopen("circle.in","r",stdin); freopen("circle.out","w",stdout); } int read() { int x = 0,f = 1; char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { x = (x << 3) + (x << 1) + c - '0'; c = getchar(); } return f * x; } struct qwq { int x,y,z; }; vector<qwq>a; int n,m; int main() { file(); n = read(); int ans = 0; for(int i = 1;i < n;i++) { for(int j = i + 1;j < n;j++) { if(i + j < n) { if(n - i - j <= i || n - i - j <= j) continue; ans++; a.push_back((qwq){i,j,n - i - j}); } else { if(2 * n - i - j <= i || 2 * n - i - j <= j) continue; ans++; a.push_back((qwq){i,j,2 * n - i - j}); } } } int l = a.size(); printf("Yes\n%d\n",ans); for(int i = 0;i < l;i++) { printf("%d %d %d\n",a[i].x,a[i].y,a[i].z); } }