嘘~ 正在从服务器偷取页面 . . .

CF219D Choosing Capital for Treeland 题解


CF219D Choosing Capital for Treeland 题解

题目链接:CF219D Choosing Capital for Treeland

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

随便找一个点 \(rt\) 跑一遍dfs,求出这个 \(dp[rt]\) 的值

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

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

代码:

#include <bits/stdc++.h>
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<n; 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;
}

题外话

真的离了谱了,我换电脑之前写的这篇文章没发博客上

然后今天20220606花了2小时用爬虫和自己写的比对程序搞了半天才发现(恼


upd.20240503 至少现在不用担心了。


文章作者: q779
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 q779 !
评论
  目录