环形划分

题目大意:你有一个 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);
    }
}
非常水的参考代码

 

posted @ 2019-06-27 16:40  锦依卫Lijilai  阅读(243)  评论(0编辑  收藏  举报