题目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;
}