首页 > 其他分享 >CSP模拟23

CSP模拟23

时间:2023-08-17 20:22:05浏览次数:32  
标签:EndPoint dist 23 int CSP fa const operatorname 模拟

电压、农民、奇迹树、暴雨

来自 \(\texttt{happyguy}\) 的馈赠。

A. 电压

我们考虑选一条边作为那条两边结点相同的边。

首先考虑,如果不选奇环上的边。奇环上的边一定有两端结点颜色相同的,所以如果图中有奇环,奇环上的边一定被选择。

考虑偶环,偶环上的边一定不能被选,选了的话偶环上的边也必定有一条左右结点颜色相同。

所以,如果没有奇环,那么除了偶环之外的边都能选。

如果有奇环,那么必须要选的是奇环上边的交集,并且还要保证这条边不在偶环上。

如果只有一个奇环,要记得把非树边加上。

最后树上差分求。

#include <bits/stdc++.h>

using namespace std;

const int N = 100500;

int n,m;

struct Edge{
    int next,to;
}e[N << 2];

int cnt = 1,h[N];

int root[N];

void Add(int u,int v) {
    cnt ++;
    e[cnt].next = h[u];
    h[u] = cnt;
    e[cnt].to = v;
}

bool vis[N];
int dep[N];

int sum[N][2];

int tot;// 奇环个数 

int fa[N];
// 这个点上面那条边的编号 

void dfs(int x) {
    vis[x] = 1;

    for(int i = h[x];i;i = e[i].next) {
        int to = e[i].to;

        if(i == fa[x] || (i ^ 1) == fa[x])
            continue;// 防止走回去 
        
        if(vis[to]) {
            // 非树边 
            if(dep[to] > dep[x])
                continue;
            
            int d = (dep[x] - dep[to]) & 1;
            // 判奇偶环 

            sum[x][d] ++;
            sum[to][d] --;

            if(d == 0)
                tot ++;
        }
        else {
            fa[to] = i;
            dep[to] = dep[x] + 1;
            dfs(to);
            
            sum[x][0] += sum[to][0];
            sum[x][1] += sum[to][1];
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin >> n >> m;

    for(int i = 1,u,v;i <= m; i++) {
        cin >> u >> v;
        Add(u,v);
        Add(v,u);
    }

    for(int i = 1;i <= n; i++) {
        if(!vis[i]) {
            root[i] = 1;
            dfs(i);
        }
    }

    int ans = 0;

    for(int i = 1;i <= n; i++)
        if(sum[i][0] == tot && !sum[i][1] && !root[i])
            ans ++;// 在所有奇环上 
    
    if(tot == 1)
        ans ++;
    cout << ans << "\n";
    return 0;
}

B. 农民

C. 奇迹树

题目大意

给定一棵 \(n\) 个节点的树,要求构造出一个点权序列 \(E\),满足以下三个条件:

  1. 所有 \(E_i\ge 1(1\le i\le n)\)。
  2. 对于任意一组 \((i,j)(1 ≤ i < j ≤ N)\),使 \(|E_i-E_j|\geq \operatorname{dist}(i,j)\),\(\operatorname{dist}(i,j)\) 即树上 \(i\) 和 \(j\) 两点距离。
  3. 使 \(E\) 中的最大值最小。

思路

首先只考虑前两个限制,设有点 \(i,j,k\) 满足

\[E_i < E_j < E_k \]

因为有

\[E_k-E_i=E_k-E_j+E_j-E_i \]

由于

\[E_k-E_j\geq \operatorname{dist}(k,j),E_j-E_i\geq \operatorname{dist}(i,j) \]

所以有

\[E_k-E_i \geq \operatorname{dist}(k,j) + \operatorname{dist}(i,j) \]

又因为

\[\operatorname{dist}(k,j) + \operatorname{dist}(i,j) \geq \operatorname{dist}(i,k) \]

使得 \(E_k-E_j\) 尽可能小,得到

\[E_k-E_i=\operatorname{dist}(k,i) \]

那么我们直接可以用欧拉序列进行构造,欧拉序列的长度为 \(2n - 1\)。

再考虑第三个限制条件,让 \(E\) 中的最大值最小。

考虑我们欧拉序列有重复走的部分,我们使那个重复走的链的部分最短,那么那一段我们就可以选取树的直径。

那么我们怎么保证固定我们最后走哪个点呢?如果一条边在直径上,我们就最后经过这条边,这样在到达直径的第二个端点时,能够保证其他的点都已经遍历过。

#include <bits/stdc++.h>

using namespace std;

const int N = 200500;

vector<int> e[N];

int n;

int dis[N];

int EndPoint,End;

void dfs1(int x,int fa) {
    dis[x] = dis[fa] + 1;

    if(dis[x] > dis[EndPoint])
        EndPoint = x;
    
    for(auto const &to : e[x]) {
        if(to == fa)
            continue;
        
        dfs1(to,x);
    }
}

void GetCal() {
    dfs1(1,0);

    End = EndPoint;

    dfs1(EndPoint,0);
}

bool cal[N];

void dfs2(int x,int fa) {
    if(x == End)
        cal[x] = 1;
    for(auto const &to : e[x]) {
        if(to == fa)
            continue;
        
        dfs2(to,x);
        cal[x] |= cal[to];
    }
}

int ans[N],tot;

void dfs3(int x,int fa) {
    tot ++;
    ans[x] = tot;

    for(auto const &to : e[x]) {
        if(to == fa || cal[to])
            continue;
        
        dfs3(to,x);
        tot ++;
    }

    for(auto const &to : e[x]) {
        if(to == fa || !cal[to])
            continue;
        
        dfs3(to,x);
    }
}

int main() {
    cin >> n;

    for(int i = 1,u,v;i < n; i++) {
        cin >> u >> v;
        e[u].emplace_back(v);
        e[v].emplace_back(u);
    }

    GetCal();
    
    dfs2(EndPoint,0);
    dfs3(EndPoint,0);

    for(int i = 1;i <= n; i++) 
        cout << ans[i] << " ";
    
    cout << "\n";
    return 0;
}

D. 暴雨

标签:EndPoint,dist,23,int,CSP,fa,const,operatorname,模拟
From: https://www.cnblogs.com/baijian0212/p/csp-23.html

相关文章

  • 「Log」2023.8.17 小记
    序幕早上到校先摆,然后开调代码。大分块对拍调调调。学长开始讲平衡树。平衡树平衡树平衡树!学完了,点午饭吃午饭。学主席树。主席树主席树主席树!学完了点晚饭吃完饭。用chatGPT写了点文章,乐坏了。继续卡常。\(\color{black}{P4119\[Ynoi2018]\未来日记}\)详见「「No......
  • 【题解】#373. 「USACO1.1」Friday the Thirteenth 题解(2023-07-19更新)
    #373.「USACO1.1」FridaytheThirteenth题解本文章的访问次数为次。Part1提示题目传送门欢迎大家指出错误并私信这个蒟蒻欢迎大家在下方评论区写出自己的疑问(记得@这个蒟蒻)Part2背景这个蒟蒻又一次写了一篇大水题的题解(话说为什么是又),当然也是为了纪念他的\(......
  • 【考后总结】CSP-S 模拟 6
    8.17CSP模拟23That'sWhyYouGoAway-MichaelLearnsToRockBabywon'tyoutellmewhythereissadnessinyoureyesIdon'twannasaygoodbyetoyouLoveisonebigillusionIshouldtrytoforgetButthereissomethingleftinmyhea......
  • 【题解】#68. 「NOIP2004」津津的储蓄计划 题解(2023-07-19更新)
    #68.「NOIP2004」津津的储蓄计划题解本文章的访问次数为次。Part1提示题目传送门欢迎大家指出错误并私信这个蒟蒻欢迎大家在下方评论区写出自己的疑问(记得@这个蒟蒻)Part2背景这是这个蒟蒻的第一篇题解,也是这个蒟蒻对自己的\(50\)AC的纪念。Part3更新日志......
  • 黑魂232 导演动画
    创建一个空物体,改名Director。把Playable放进去, 然后在黑骑士模型里增加两个空物体作为开关武器的按钮,然后分别把武器放进去。 然后要将剑盾里的插件修改成filter和MeshRenderer: 然后在脚本文件夹里新建一个Timeline插件: 这里是要先将Director物体绑定好刚刚创建的t......
  • 2023.8.17 - env运行时变量在node中运行问题
    在Vue.js中,你不能直接在模板文件中访问.env文件中定义的环境变量。.env文件中的变量是在构建过程中被注入到应用程序中的,而不是在运行时可访问的。然而,你可以使用Vue提供的process.env来访问在构建过程中注入的环境变量。在Vue组件的JavaScript代码中,你可以通过process.env.VARIA......
  • Python学习日记 2023年8月17日
    今天有点懒啊,做的东西少了点importosimportjiebaimportwordcloudimportimageio#pho=imageio.imread('7848.jpg')f=open('口红.txt')txt=f.read()txt_list=jieba.lcut(txt)string=''.join(txt_list)wc=wordcloud.WordCloud(......
  • 2023年 Java 面试八股文(20w字)
    第一章-Java基础篇1、你是怎样理解OOP面向对象难度系数:⭐面向对象是利于语言对现实事物进行抽象。面向对象具有以下特征:继承:继承是从已有类得到继承信息创建新类的过程封装:封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口多态性:多态性是指允许不同......
  • 暑假牛客多校第九场 2023-8-15(D、I)
    未补完D.Non-Puzzle:ErrorPermutation算法:差分做法:   考虑题目的数据,我们的做法可以先枚举出不合法的区间数,然后由区间总数减去不合法区间数。我们首先确定一个数,令这个数就是包含这个数的一段区间的不和法值,即这个数是第\(i\)小的数。一开始我们使这段区间大小......
  • .NET Core 单元测试 - 模拟 IOptions<T>
    技术标签:【中文标题】.NETCore单元测试-模拟IOptions<T>【英文标题】:.NETCoreUnitTesting-MockIOptions<T>【发布时间】:2017-04-1401:49:54【问题描述】:我觉得我在这里遗漏了一些非常明显的东西。我有需要使用.NETCore IOptions 模式(?)注入选项的类。当我对该类......