首页 > 其他分享 >CF1218G Alpha planetary system 题解

CF1218G Alpha planetary system 题解

时间:2022-12-08 18:34:17浏览次数:62  
标签:rt head int 题解 sum CF1218G 权值 Alpha col

Part 1

设 \(w_x\) 表示点 \(x\) 的权值 \(\bmod 3\),\(c_x\) 表示 \(x\) 的所属集合编号(\(c_x \in \{0,1,2\}\)),\(v_i\) 表示第 \(i\) 条边的权值。

一个直接的想法是使所有 \(w_x=c_x\),当然这不一定能做到,具体见下文。

首先,根据套路,随便建一颗生成树出来。设根为 \(rt\)。

先将所有非树边权值设为 \(3\)。对于点 \(u\),若其子树内所有树边权值都确定了,则 \(u\) 到父亲的树边的权值可以唯一确定。

然而,\(rt\) 没有到父亲的边,此时要做出调整:

  1. 如果此时 \(w_{rt}=c_{rt}\),则方案已经合法。
  2. 否则,我们需要找到包含 \(rt\) 的一个环进行调整。

Part 2

提取出包含 \(rt\) 的一个环,设环上的编号依次为 \(e_1,e_2,\dots,e_k\),其中 \(e_1,e_2\) 两条边均有一个端点是 \(rt\)。

偶环是没用的,因为在偶环上对权值调整只能形如 \(v_{e_1}+1,v_{e_2}+2,v_{e_3}+1,v_{e_4}+2,\dots\),无法改变任何一点的权值。

奇环是有用的,考虑如下调整:

  • 当 \(w_{rt}+1\equiv c_{rt} \pmod 3\),执行 \(v_{e_1}+2,v_{e_2}+2,v_{e_3}+1,v_{e_4}+2,v_{e_5}+1,\dots\)。显然环上除了 \(rt\) 其他点的权值均未改变。
  • 当 \(w_{rt}+2\equiv c_{rt} \pmod 3\),执行 \(v_{e_1}+1,v_{e_2}+1,v_{e_3}+2,v_{e_4}+1,v_{e_5}+2,\dots\)。

因此,当原图中存在奇环,将 \(rt\) 取奇环上的任意一点,一定可以构造出合法方案。

Part 3

如果没有奇环呢?容易想到原图是二分图

考虑重新将所有点划分为 \(2\) 个集合,这可以通过二分图染色实现。设 \(c_x\) 表示 \(x\) 新的所属集合编号(\(c_x \in \{1,2\}\))。

不失一般性地设 \(c_{rt}=1\),还是像 Part 1 那样将处理树边,最后考虑 \(rt\) 的情况:

  1. \(w_{rt} \ne 2\)。此时方案已经合法。因为对于与 \(rt\) 之间有边的点 \(u\) 必有 \(w_u=2 \ne w_{rt}\)。
  2. \(rt\) 的度数 \(=1\)。此时方案已经合法。设与 \(rt\) 之间有边的点为 \(u\),显然 \(u\) 的度数 \(>1\),则 \(u\) 的权值必然 \(>\) \(rt\) 的权值。
  3. \(w_{rt}=2\) 且 \(rt\) 的度数 \(>1\)。选出与 \(rt\) 之间有边的两个点 \(u,v\),将 \((rt,u),(rt,v)\) 两条边的权值 \(+1\) 即可。调整后 \(w_{rt}=1,w_u=w_v=0\),可以证明满足要求。

代码实现不难。

#include <bits/stdc++.h>

using namespace std;

using i64=long long;
using u64=unsigned long long;
using db=double;
using pii=pair<int,int>;
using vi=vector<int>;

template<typename T>
inline T read(){
    T x=0,f=0;char ch=getchar();
    while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
    while(isdigit(ch)) x=x*10+(ch-'0'),ch=getchar();
    return f?-x:x;
}

#define rdi read<int>
#define rdi64 read<i64>
#define fi first
#define se second
#define pb push_back

const int N=2e5+10;

int n,m,typ[N];
char s[N];

struct Edge{int to,nxt,fl,w;}e[N];
int head[N],tot=1,deg[N];

void add_e(int x,int y){
    e[++tot]={y,head[x],0,0};
    head[x]=tot,++deg[x];
}

bool odd_lp;
int col[N];
void dfs(int x,int c=1){
    col[x]=c;
    for(int i=head[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(!col[y]) e[i].fl=e[i^1].fl=1,dfs(y,3-c);
        else if(col[y]==col[x]) odd_lp=true;
    }
}

namespace S1{
    int sum[N];
    void dfs1(int x,int fa){
        for(int i=head[x];i;i=e[i].nxt){
            if(!e[i].fl) continue;
            int y=e[i].to;
            if(y!=fa) dfs1(y,x),sum[x]+=e[i].w;
        }
        for(int i=head[x];i;i=e[i].nxt){
            if(e[i].fl&&e[i].to==fa){
                e[i].w=e[i^1].w=(col[x]+3-sum[x]%3)%3;
                sum[x]=col[x];break;
            }
        }
    }
    void solve(){
        int rt=find(col+1,col+n+1,1)-col;
        dfs1(rt,0);
        if(deg[rt]>1&&sum[rt]%3==2){
            int i1=head[rt],i2=e[i1].nxt;
            e[i1].w++,e[i1^1].w++,e[i2].w++,e[i2^1].w++;
        }
    }
}

namespace S2{
    int rt,u,sum[N],tofa[N];
    void dfs1(int x,int fa){
        for(int i=head[x];i;i=e[i].nxt){
            if(!e[i].fl) continue;
            int y=e[i].to;
            if(y!=fa) dfs1(y,x),sum[x]+=e[i].w;
        }
        for(int i=head[x];i;i=e[i].nxt){
            if(e[i].fl&&e[i].to==fa){
                e[i].w=e[i^1].w=(typ[x]+3-sum[x]%3)%3;
                sum[x]=typ[x],tofa[x]=i;
                break;
            }
        }
    }

    void adjust(){
        if(sum[rt]%3==typ[rt]%3) return;
        vi cyc;int x=u;
        while(x!=rt) cyc.pb(tofa[x]),x=e[tofa[x]].to;
        for(int i=head[rt];i;i=e[i].nxt)
            if(!e[i].fl&&e[i].to==u) {cyc.insert(cyc.begin(),i);break;}
        int val=(sum[rt]+1)%3==typ[rt]%3?2:1;
        for(auto id:cyc) e[id].w+=val,e[id^1].w+=val,val=3-val;
    }

    void solve(){
        for(int x=1;x<=n;x++){
            bool fl=0;
            for(int i=head[x];i;i=e[i].nxt)
                if(col[e[i].to]==col[x]){
                    fl=1,rt=x,u=e[i].to;
                    break;
                }
            if(fl) break;
        }
        dfs1(rt,0),adjust();
    }
}

void output(){
    for(int i=2;i<=tot;i+=2){
        int x=e[i^1].to,y=e[i].to,w=(e[i].w+2)%3+1;
        cout<<x-1<<' '<<y-1<<' '<<w<<'\n';
    }
}

int main(){
    n=rdi(),m=rdi();
    scanf("%s",s+1);
    for(int i=1;i<=n;i++) typ[i]=s[i]-'X'+1;
    for(int i=1;i<=m;i++){
        int x=rdi()+1,y=rdi()+1;
        add_e(x,y),add_e(y,x);
    }
    dfs(1);
    if(odd_lp) S2::solve();
    else S1::solve();
    output();
    return 0;
}

标签:rt,head,int,题解,sum,CF1218G,权值,Alpha,col
From: https://www.cnblogs.com/acceptedzhs/p/sol-cf1218g.html

相关文章

  • undefined reference to vtable for问题解决(QT)
    主要在运行时出现原因是在自定义类使用信号与槽,在创建文件时,未继承QObject类并且没有添加Q_OBJECT;解决:在需要的类中,添加Q_OBJECT,继承QObject类。然后使用QTCreator工......
  • labelme 安装使用及常见问题解决
    (目录)写在前面,本文为作者本人在学习使用labelme过程中遇到的各种问题,记录于此,希望对其他同学有所帮助。1.labelme安装labelme是麻省理工(MIT)的计算机科学和人工智能实验......
  • ARC145~152 题解
    比赛标号从大到小排列.因为博主比较菜所以没有题解的题都是博主不会做的/youlARC144以前的比赛懒得写了.目录AtCoderRegularContest152B.PassonPathC.PivotD......
  • Team them up!题解
    Teamthemup!题面你的任务是按照以下要求将一些人员划分到两个队伍中。每个人都属于其中的一个队伍。每个队伍至少包含一个人。每个人都认识几个人,而同一个队伍中的......
  • .NET 6 中外部引用项目NU1105异常问题解决
    .NET6Project中,添加了其他解决方案的工程后,本地能编译通过,代码签入后,其他同事下载代码,编译报错:错误NU1105找不到“E:\Teld\01Code\TTP_CTP\_git\TTP_CTP_NET6\Src\Fr......
  • Pycharm cannot set up a python SDK问题解决方法
    xcrun:error:invalidactivedeveloperpath(/Library/Developer/CommandLineTools),missingxcrun...解决方法:打开终端输入xcode-select--install回车后,系统......
  • POM net.sf.json-lib:json-lib报错问题解决
    在配置项目的Jackson的时候,需要添加依赖<dependency><groupId>net.sf.json-lib</groupId><artifactId>json-lib</artifactId><......
  • Python——问题解决:matplotlib.pyplot绘制函数中文乱码
    代码frompylabimportmpl#中文库mpl.rcParams['font.sans-serif']=['SimHei']mpl.rcParams['axes.unicode_minus']=False例子plt.title("三次样条插值11点")plt.pl......
  • vue 多级嵌套路由,页面不变化问题解决
      component:{render(c){returnc('router-view')}},redirect:'/set/origin',在二级路由出添加上面的代码,并重定向二级路由页面就可以了......
  • 某行业比赛部分WEB题解题思路
    login.php源码如下:<?phperror_reporting(0);highlight_file(__FILE__);include_once("flag.php");$data=['username'=>'admin','password'=......