首页 > 其他分享 >AGC064B 题解

AGC064B 题解

时间:2024-08-03 17:40:43浏览次数:9  
标签:AGC064B xleftrightarrow 连通 int 题解 cin fa find

设红色的点值为 0,蓝色为 1。

注意到,如果有一条边的颜色和两端点同色,一定可以选。

例子:

选择和两端点同色的边。

又发现,如果存在一个 \(sz>1\) 的合法连通块,无论和其他点怎么连,原来的这个连通块内的点一定合法。

有注意到形如 \(0\xleftrightarrow 10,1\xleftrightarrow 01\) 类型的边,除了连接两个 \(sz>1\) 的块外,无用。

那么 \(0\xleftrightarrow x1\) 这样的呢?

注意到,只用上面这种边不可能形成一个连通块,因为每次加入这种边的时候,一定只会满足一边,没有被满足的点只会移动而不会消失。

如图,即使贪心染色,根节点也无法满足。

所以,一定是从一开始的一些大连通块开始,沿着 \(0\xleftrightarrow 11\) 这样的边搜索。

搜索有点细节,因为加入孤立点要先满足孤立点的需求,所以 \(0\xleftrightarrow x1\) 的边的搜索方向应该是 \(!x\to x\)。

最后合并成几个大连通块。

然后用 \(0\xleftrightarrow 10,1\xleftrightarrow 01\) 类型的边合并,就做完了。

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

const int N = 2e5 + 5;
int fa[N], n, m;

int find(int x) {return x == fa[x] ? x : fa[x] = find(fa[x]);}
inline bool conn(int x, int y) {return find(x) == find(y);}
void merge(int x, int y) {fa[find(x)] = find(y);}

int u[N], v[N], w[N], c[N];
bool ok[N], ch[N];

vector<pair<int, int>> e[N];

signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= n; i ++) fa[i] = i;
    for(int i = 1; i <= m; i ++)
    {
        char c; cin >> u[i] >> v[i] >> c;
        w[i] = c == 'R';
    }
    string s; cin >> s;
    for(int i = 1; i <= n; i ++)
        c[i] = s[i - 1] == 'R';
    for(int i = 1; i <= m; i ++)
    {
        int x = u[i], y = v[i], z = w[i];
        if(conn(x, y)) continue;
        if(z == c[x] && z == c[y])
            merge(x, y), ok[x] = ok[y] = 1, ch[i] = 1;
        else if(z == c[x]) e[y].push_back({x, i});
        else if(z == c[y]) e[x].push_back({y, i});
    }
    queue<int> q;
    for(int i = 1; i <= n; i ++) if(ok[i]) q.push(i);
    while(q.size())
    {
        int t = q.front(); q.pop();
        for(auto [i, id] : e[t])
            if(!conn(t, i))
            {
                ch[id] = 1;
                merge(t, i);
                if(!ok[i]) q.push(i);
                ok[i] = 1;
            }
    }
    for(int i = 1; i <= n; i ++)
        if(!ok[i]) return cout << "No", 0;
    for(int i = 1; i <= m; i ++)
        if(!conn(u[i], v[i])) merge(u[i], v[i]), ch[i] = 1;
    cout << "Yes\n";
    for(int i = 1; i <= m; i ++)
        if(ch[i]) cout << i << " ";

    return 0;
}

标签:AGC064B,xleftrightarrow,连通,int,题解,cin,fa,find
From: https://www.cnblogs.com/adam01/p/18340839

相关文章

  • P9351 题解
    P9351思路观察到一次覆盖操作相当于\((u,v)\)向\((u,v)\)为中心的一个矩形挖去四个角中每个点连代价为\(1\)的边。因为\(r\lec\),\(r\le\sqrt{rc}\)。暴力是01bfs,到每个点处理覆盖操作时枚举行一边,用\(n\)个并查集维护每行没有被删去的后继。对于每个点需要枚举\(......
  • 20240803题解
    话说T3都把式子推出来了结果忘记差分约束怎么写了。光线(light)题面:有\(n\)个玻璃板,第\(i\)个玻璃板的透光率为\(a_i\%\),反射率为\(b_i\%\),有大小为\(1\)个单位的一束光从第\(1\)个玻璃板开始,有多少光能穿透\(n\)层玻璃板。题解:考虑\(n=2\)时,可以简单算出两个玻璃板组合后的反......
  • 第三次测试题解
    问题F:求多个数的最大公约数multigcd[1*]:`#includeincludeincludeincludeusingnamespacestd;intfun(inta,intb){returnb==0?a:fun(b,a%b);}intmain(){intn;cin>>n;vectora(n+1,0);for(inti=1;i<=n;i++)scanf("%d",&a[i]);intans......
  • 镜面质数 题解
    题目id:20313题目描述如果一个质数镜像反转(即将该数各个位上数字反转)后仍然是质数,那么就称这个质数为镜像质数。例如质数\(13\)反转后为\(31\),则\(13\)为一个镜像质数。现在给定一个整数\(N\),请求出整数\(1\simN\)范围内有几个镜像质数。注意:求范围内的镜像质数时,质数和镜像反......
  • CF1946F Nobody is needed 题解
    Nobodyisneeded推销我的洛谷博客。题意多组数据。给定一个长度为\(n\)的排列\(a\),你需要回答\(q\)组询问,每组询问给出\(l,r\),求有多少个子序列\(t\)使得:\(l\leqslantt_1<t_2<\cdots<t_k\leqslantr\)。\(a_{t_i}|a_{t_{i+1}}(1\leqslanti<k)\)......
  • NSSCTF Web 题解 Write up
    NSSCTFWeb题解Writeup一、Do_you_know_http1、开题2、分析页面显示请使用“WLLM”浏览器,我没听说过“WLLM”浏览器,那首先去User-Agent修改访问的浏览器。用HackBar分析,将UA的值改成WLLM。用EXECUTE请求页面显示你只可以在本地正常阅读,并给出了ip。那简单,还是用HackB......
  • AGC013B 题解
    注意到只要随便dfs,如果没有可以走的点,说明这个端点满足要求。因为有两个端点,所以从同一个点开始搜两次,拼在一起就行了。#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintN=1e5+5;vector<int>e[N];intn,m;boolvis[N];voiddfs(in......
  • AGC009B 题解
    注意到如果把每一对胜者败者连边,可以得到一颗树:(例子)但是因为胜者每次只能和一个败者打,所以要用类似多叉转二叉的方法,让有不止一个孩子的节点变成有一个孩子和一个虚点。如图,原来\(1\)有三个儿子\(2,3,4\),通过转换,变成了上图。上图可以直接变成对战图(\(x2\tox1\to1)\):(原......
  • AGC049A 题解
    弱化版:CF280CGameonTree(有向图的限制变成一棵根节点为1的外向树)弱化版解法:根据期望线性性,\(Ans=\sum_{i=1}^nE(p_i)\)。其中\(p_i\)是\(i\)被选到的概率。因为对于\(i\)和\(i\)的祖先节点,某个点在这些店里是第一个备选的概率相同。所以\(p_i=\dfrac{1}{dep_i}\)......
  • joisc2017 D3T1 长途巴士 题解
    joisc2017D3T1长途巴士题解这是学校ACM欢乐赛的题,赛时想到做法了,但是因为我各种唐诗没写出来翻了转化题面我们发现,只可以踢掉检查站前面一个连续段的接水人,并且不能踢掉司机,考虑画出对整个路程表示的线段上图几个小点是检查点,考虑在每个检查点之前踢掉一段的人,容易发......