栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

CF219D Choosing Capital for Treeland 题解

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

CF219D Choosing Capital for Treeland 题解

CF219D Choosing Capital for Treeland 题解

题目链接:CF219D Choosing Capital for Treeland

题意:Treeland国有n个城市,这n个城市连成了一颗树,有n-1条道路连接了所有城市。每条道路只能单向通行。现在政府需要决定选择哪个城市为首都。假如城市i成为了首都,那么为了使首都能到达任意一个城市,不得不将一些道路翻转方向,记翻转道路的条数为k。你的任务是找到所有满足k最小的首都。

随便找一个点 r t rt rt 跑一遍dfs,求出这个 d p [ r t ] dp[rt] dp[rt] 的值

然后 d p [ u ] → d p [ v ] dp[u] to dp[v] dp[u]→dp[v] 的转移显然与 ( u , v ) (u,v) (u,v) 有关

判断一下然后转移一下就没了

题外话:真的离了谱了,我换电脑之前写的这篇文章没发博客上,然后今天20220606花了2小时用爬虫和自己写的比对程序搞了半天才发现(恼

代码:

#include 
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
#define N (int)(2e5+15)
struct Edge
{
    int u,v,next;
}e[N<<1];
int n,dp[N];
int pos=1,head[N],r[N<<1];
void addEdge(int u,int v)
{
    e[++pos]={u,v,head[u]};
    head[u]=pos;
}
int dfs1(int u,int f)
{
    int res=0;
    for(int i=head[u]; i; i=e[i].next)
    {
        int v=e[i].v;
        if(v==f)continue;
        if(!r[i])++res;
        res+=dfs1(v,u);
    }
    return res;
}
void dfs2(int u,int f)
{
    dp[u]+=dp[f];
    for(int i=head[u]; i; i=e[i].next)
    {
        int v=e[i].v;
        if(v==f)continue;
        if(r[i])++dp[v];
        else --dp[v];
        dfs2(v,u);
    }
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    // freopen("check.in","r",stdin);
    // freopen("check.out","w",stdout);
    cin >> n;
    for(int i=1,u,v; i
        cin >> u >> v;
        addEdge(u,v);r[pos]=1;
        addEdge(v,u);
    }
    dp[1]=dfs1(1,0);int mn=INF;
    dfs2(1,0);
    for(int i=1; i<=n; i++)
        mn=min(mn,dp[i]);
    cout << mn << endl;
    for(int i=1; i<=n; i++)
        if(dp[i]==mn)cout << i << " ";
    return 0;
}

转载请说明出处

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/958162.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号