【Henu ACM Round#16 C】Graph and String

【链接】 我是链接,点我呀:)
【题意】

在这里输入题意

【题解】

根据题意:先明确以下规则:
1.如果两个点之间没有边,那么这两个点只能是a或c,且不能相同
2.如果两个点之间有边,那么他们之间的差的绝对值<=1

那么对于点i,如果它和所有的点都相连了,那么就干脆把他变成b.
这样其他点无论选什么都和它没有关系,其他点选什么都可以了

接下里,找到任意一个点j,且点j没有和所有的点相连。
显然这个点只能为a或c,因为它和某个点之间没有边。【规则1】

那么我们就让这个点j设置为a;

①然后对于和j相连的所有点k,且点k不为b(即k不与其他所有点相连),那么点k
只能为a或c(因为k和某个点之间没有边)【规则1】
而根据【规则2】可知点k只能为a

②对于和j不相连的所有点k,显然k只能为c

根据①和②
会发现所有的点都已经染上色了
而点j为a或c其实不影响答案。

所以再O(n^2)根据规则判断一下这个染色是否可行就好了。

【代码】

#include <bits/stdc++.h>
using namespace std;

const int N = 500+10;

int c[N],n,m,chu[N+10];
bool b[N][N];

int main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    #ifdef LOCAL_DEFINE
        freopen("rush.txt","r",stdin);
    #endif

    cin >> n >> m;
    for (int i = 1;i <= m;i++){
        int x,y;
        cin >> x >> y;
        b[x][y] = b[y][x] = true;
        chu[x]++;chu[y]++;
    }

    for (int i = 1;i <= n;i++)
        if (chu[i]==(n-1))
            c[i] = 2;

    for (int i = 1;i <= n;i++)
        if (c[i]!=2){
            c[i] = 1;
            for (int j = 1;j <= n;j++)
                if (b[i][j] && c[j]!=2){
                    c[j] = 1;
                }else if (i!=j && !b[i][j]){
                    c[j] = 3;
                }
            break;
        }

    for (int i = 1;i <= n;i++)
        for (int j = 1;j <= n;j++)
            if (b[i][j]){
                if (abs(c[i]-c[j])>1) return cout<<"No"<<endl,0;
            }else if (i!=j){
                if (abs(c[i]-c[j])<=1) return cout<<"No"<<endl,0;
            }
    cout<<"Yes"<<endl;
    for (int i = 1;i <= n;i++){
        if (c[i]==1) cout<<'a';
        if (c[i]==2) cout<<'b';
        if (c[i]==3) cout<<'c';
    }
    return 0;
}

原文地址:https://www.cnblogs.com/AWCXV/p/8358933.html

时间: 2024-08-30 07:57:35

【Henu ACM Round#16 C】Graph and String的相关文章

【Henu ACM Round#16 B】 Bear and Colors

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] O(n^2)枚举每一个区间. 然后维护这个区间里面的"统治数字"是什么. 对于每个区间cnt[统治数字]++; [代码] #include <bits/stdc++.h> using namespace std; const int N = 5000+10; int n; int t[5000+10]; int num[5000+10],cnt[N]; int main() { ios::sync_with

【Henu ACM Round#16 D】Bear and Two Paths

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 先搞一条a到b的路径 a c x3 x4 x5....xn-2 d b 然后第二个人的路径可以这样 c a x3 x4 x5...xn-2 b d 也即加两条边[a,x3] [xn-2,b] 所以最少只需要n+1条边. (尽量让边共用,只有两条边是需要特殊加进去的 (可以这样理解,加一条边的话,无论怎么加都不够的.所以加两条肯定是最优的了. 这样贪就好了 但是n=4的时候:' 会发现两对起点和终点中肯定有一对是有一条边**直接相

【Henu ACM Round #13 C】 Ebony and Ivory

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 先求出c-bx的所有可能 ->存在map里面 然后枚举y看看ay在不在map里面 在的话就有解. 这样复杂度是\(O(N*log_2N)\)的 比直接两层循环枚举的\(O(N^2)\)复杂度要来的好 这种方法也叫"中途相遇法" [代码] #include <bits/stdc++.h> #define ll long long using namespace std; ll a,b,c; map<

【Henu ACM Round #13 B】Spider Man

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 会发现每个环可以操作的次数是固定的. (环的大小-1 也就是说一旦环确定了.其实结果就已经确定了. 则直接看操作总数的奇偶性就可以了. [代码] #include <bits/stdc++.h> #define long long using namespace std; int n,x; int main(){ #ifdef LOCAL_DEFINE freopen("rush_in.txt", &quo

【Henu ACM Round #13 D】A Trivial Problem

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 123...n中末尾0的个数 只会由素因子2和5的个数决定且等于 Min{cnt[2],cnt[5]} 且素因子2的个数一定会比5多; 所以n!的末尾0的个数 等于for (int i = 1;i <= n;i++)中所有i的5因子的个数和 枚举一下就好 [代码] #include <bits/stdc++.h> using namespace std; const int N = 1e7; int n; vector&

【Henu ACM Round #13 E】Spy Syndrome 2

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 对m个串建立一棵字典树. 然后对主串. 尝试从第一个位置开始.在字典树中尝试匹配 如果匹配到了位置i 就再从位置i+1开始尝试匹配 (这时又重新从根节点开始重新匹配 每次匹配最多只要往下走50步. 写个递归的过程就好. [代码] #include <bits/stdc++.h> using namespace std; const int N = 1e6; const int NN = 1e4; const int M = 1

【Henu ACM Round#14 A】Vitaly and Night

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 连续两个如果不全是0就递增cnt [代码] #include <bits/stdc++.h> using namespace std; int n,m; int main() { cin >> n >>m; int cnt = 0; for (int i = 1;i <= n;i++){ int x,y; for (int j = 1;j <= m;j++){ cin >>x &

【Henu ACM Round#14 C】Duff and Weight Lifting

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 2^y可以由两个2^(y-1)相加得到. 则有一个贪心的策略. 就是2^x尽量都变成2^(x+1) (即能够凑就尽量凑) 如果x还有剩余的话.答案递增1 而凑上去的数字,显然是可以合并成1步操作的.因为他们的和就是2^(x+1) [代码] #include <bits/stdc++.h> #define ll long long using namespace std; const int N = 1e6; int n,a[N

【Henu ACM Round#15 E】 A and B and Lecture Rooms

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 最近公共祖先. (树上倍增 一开始统计出每个子树的节点个数_size[i] 如果x和y相同. 那么直接输出n. 否则求出x和y的最近公共祖先.z (假定y的深度大于x [1]如果z等于x或y中的一个. 那么久就找到x..y的路径(长度设为L)中的中点u. 显然,u和它的其他len-1个子树上的任意一个节点都是可行的(除了那个包含y的子树 设_get(x,step)表示x节点往上走step步到达的节点 则输出_sum[中点]-_s