题意:
太长了自己看
题解:
缩点,每个强连通分量的最小价格就是分量中所有点最小的价格,再根据贪心,只有那些不能被其他强连通分量到的分量才需要买
#include<iostream>
#include<sstream>
#include<string>
#include<queue>
#include<map>
#include<unordered_map>
#include<set>
#include<vector>
#include<stack>
#include <utility>
#include<list>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<time.h>
#include<random>
using namespace std;
#include<ext/pb_ds/priority_queue.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace __gnu_pbds;
#include<ext/rope>
using namespace __gnu_cxx;
#define int long long
#define PI acos(-1.0)
#define eps 1e-9
#define lowbit(a) ((a)&-(a))
const int mod = 1e9+7;
int qpow(int a,int b){
int ans=1;
while(b){
if(b&1)ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
const int INF = 0x3f3f3f3f;
const int N = 1e6+10;
int dfn[3005],low[3005],s[3005],vis[3005],in[3005],w[3005],col[3005],minw[3005];
int n,p,sum,tim,tp,cnt;
vector<int>g[3005];
int g2[3005][3005];
void tarjan(int u){
dfn[u]=low[u]=++tim,s[++tp]=u,vis[u]=1;
for(auto v:g[u]){
if(!dfn[v]){
tarjan(v);low[u]=min(low[u],low[v]);
}
else if(vis[v])low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
int x,miw=INF; cnt++;
do{
x=s[tp--],vis[x]=0,col[x]=cnt,miw=min(miw,w[x]);
}while(u!=x);
minw[cnt]=miw;
}
}
#define endl '\n'
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>p;
for(int i=1;i<=n;i++)w[i]=INF;
for(int i=1;i<=p;i++){
int id,cost; cin>>id>>cost;
w[id]=cost;
}
int m; cin>>m;
for(int i=1;i<=m;i++){
int u,v; cin>>u>>v;
g[u].push_back(v),in[v]++;
}
for(int i=1;i<=n;i++)
if(!in[i]&&w[i]==INF){cout<<"NO"<<endl<<i<<endl; return 0;}
else in[i]=0;
for(int i=1;i<=n;i++)if(!dfn[i]&&w[i]!=INF)tarjan(i);
for(int u=1;u<=n;u++){
for(auto v:g[u]){
if(col[u]==col[v]||g2[col[u]][col[v]])continue;
g2[col[u]][col[v]]=1;
if(in[col[u]]||minw[col[u]]!=INF)in[col[v]]=1;
}
}
int sum=0;
for(int i=1;i<=cnt;i++){
if(in[i])continue;
sum+=minw[i];
}
cout<<"YES"<<endl<<sum<<endl;
}