0
点赞
收藏
分享

微信扫一扫

“华为杯“ 武汉大学21级新生程序设计竞赛 J.传闻档案

进击的包籽 2022-04-05 阅读 17
算法

题目link

思路

反向建图,贪心跑bfs

反向建图权值从大到小跑bfs,来确定当前权值可以到达的点,在正常图(正向建边)中即是能到达它的点,然后开个 v i s vis vis数组记录一下点是否来过,贪心下每个点只更新一次,线性复杂度.

Code

const int inf = 0x3f3f3f3f;
const int INF = ~0ULL;
const int N = 1e6+10;
int n,m;


struct node{
    int id,w;
    bool operator<(const node&t) const{
        if(w==t.w) return id < t.id;
        return w > t.w;
    }
}a[100005];

vector<int>g[100005];
int in[100005];
int f[100005];
bool st[N];
map<int,int> mp;


void bfs(int u){
    queue<int> q;
    q.push(u);
    st[u] = 1;
    while(q.size()){
        int t = q.front();q.pop();
        for(auto i:g[t]){
            if(!st[i]){
                t = mp[i];
                a[t].w = max(a[t].w,a[mp[u]].w);
                st[i] = 1;
                q.push(i);
            }

        }

    
    }
}

signed main()
{
    cin>>n>>m;
    forr(i,1,n) cin >> a[i].w,a[i].id = i;
    while(m--){
        int u,v;
        cin>>u>>v;
        g[v].push_back(u);
    }

    sort(a+1,a+1+n);
    forr(i,1,n) mp[a[i].id] = i;
    forr(i,1,n){
        bfs(a[i].id);
    }

    int res = 0;
    forr(i,1,n) res += a[i].w;
    cout << res << endl; 
    return 0;
}
举报

相关推荐

0 条评论