立刻出行杯高年级组-E 这题只有Yes和No,跑随机测一下RP吧:)(最小生成树性质)

题解

3个点(含)及以下的显然不行,

2条边(含)及以下的显然不行,

没有3种颜色的显然不行,

剩下的一定可以。

思路来源

出题方题解

1.连通图才有生成树,所以要先判图是否连通
2.图中需要出现至少一条R边,一条G边,一条B边
3.生成树的边数>=3 (R*1+G*1+B*1),所以n>=4

不考虑重边和自环,满足以上三个条件的图一定有解

证明:图连通,可以先随便造一颗普通的生成树,对于这颗生成树
(1)若已经含有三种颜色的边,则构造完毕

(2)若只有两种颜色,假如只有R边和G边,则随便找一条B边连上,这时就形成了一个环,且这个环的边数>=3,假如环上有两条以上的R边,则随便删一条R边即可,有两条以上的G边同理,
若R边和G边各只有一条,此时这是一个三元环,由于n>=4,环外肯定存在多余的R边或G边,多余R边则删环上的R边,G边同理

(3)若只有一种颜色,假如只有R边,同理先随便找一条G边连上,形成一个环,随便删一条环上的R边,就变成了情况(2)

心得

自己图论相关还是太菜了,寒假多刷题

当时6月份看prim最小证明的时候,就是用边的替换,

kruskal也是,结果现在需要用到证明相关的替换集合,反倒不会了GG

当时比赛的时候多想一下就好了,可惜卡在H上太久,

开局莽H30minWA8发已然心态爆炸,最后能抢救回来实属不易……

诶,又痛失一个beat罗老师&&吴老师的机会,痛失2K

请记住,凡是看似擦肩而过的瞬间,都是实力的巨大差距,

秦皇岛是费用流,高级组是SG函数,而这次,是最小生成树。

一个acm选手,连大一学弟和数模学长都打不过啊哎,真是菜啊

代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=2e4+5;
int n,m,par[maxn];
bool color[3];
void init(int n)
{
    for(int i=0;i<n;++i)
        par[i]=i;
}
int find(int x)
{
    return par[x]==x?x:par[x]=find(par[x]);
}
void unite(int x,int y)
{
    x=find(x),y=find(y);
    if(x==y)return;
    if(x<y)par[y]=x;
    else par[x]=y;
}
int main()
{
    ios::sync_with_stdio(0);
    cin>>n>>m;
    init(n);
    for(int i=0;i<m;++i)
    {
        int u,v,k;
        cin>>u>>v>>k;
        color[k]=1;
        unite(u,v);
    }
    bool flag=1;
    int num=0;
    for(int i=0;i<3;++i)if(!color[i])flag=0;
    if(n<=3||m<3)flag=0;
    for(int i=0;i<n;++i)if(par[i]==i)num++;
    if(num>=2)flag=0;
    if(!flag)puts("no");
    else puts("yes");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Code92007/article/details/85250384