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

AtCoder Beginner Contest 226 C dfs序 逆拓扑序

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

AtCoder Beginner Contest 226 C dfs序 逆拓扑序

题目

一个武术高手,可以学T种武术,但他只想学第T个武术,学每个武术有需要花费的时间和前置武术条件(即要先学会前置的武术)。
求他学会第T个武术需要的最少时间。

题解思路

一开始想并查集什么的,没想太明白。
如果从图论想的话,这题就可以解决了。
如果正向建图的话,不容易得出答案的。因为起点难确定。
而如果反向建图的话,从T点出发往回跑,跑到每个武术的最基础武术点(即无需前置武术的那种)。并且每个点只跑一次。记录出来的就是答案。

帖大佬的一句话

我们反向跑的时候当这个点以及被学过了,那就没必要再跑一遍了。

参考题解

AC代码
#include 
//#include 
//priority_queue
#define PII pair
#define ll long long

using namespace std;

const  int  INF =  0x3f3f3f3f;
const  int N = 200100 ; 

vector  head[N] ; 
int a[N] ; 
int vis[N] ; 

void dfs(int p )
{
    if ( p == 0 )
        return ;
    for (int i = 0 ; i < head[p].size() ; i++ )
    {
        int st = head[p][i] ; 
        if (!vis[st])
        {
            vis[st] = 1 ;
            dfs(st) ; 
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int T ;
    cin >> T ;
    for (int j = 1 ; j <= T ; j++ )
    {
        int s , n ;
        cin >> s >> n ;
        a[j] = s ; 
        for (int i = 1 ; i <= n ; i++ )
        {
            int t1 ;
            cin >> t1 ; 
            head[j].push_back(t1) ; 
        }
    }
    dfs(T) ;
    long long ans = a[T] ;  
    for (int i = 1 ; i < T ; i++ )
        if (vis[i])
            ans += a[i] ;
    cout << ans << "n" ; 
    return 0 ;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/512570.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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