这是从 LibreOJ 上面扒下来的:
Input:
4
1
4 10
2
3 2
3 1
Output:
NO
3
Answer:
NO
1
MyCode:
//the code is from chenjh
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<vector>
int n,m,p;
int a[3003],w[3003],in[3003];
std::vector<int> G[3003];
int tot=0,col=0,dfn[3003],low[3003],scc[3003];
bool ins[3003];std::stack<int> stk;
inline void tarjan(const int u){
dfn[u]=low[u]=++tot,ins[u]=1;
stk.push(u);
for(const int v:G[u]){
if(!dfn[v]) tarjan(v),low[u]=std::min(low[u],low[v]);
else if(ins[v]) low[u]=std::min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
w[scc[u]=++col]=a[u];
for(;!stk.empty() && stk.top()!=u;stk.pop()){
scc[stk.top()]=col,ins[stk.top()]=0;
if((w[col]<0 && a[stk.top()]>=0)||(w[col]>=0 && 0<=a[stk.top()] && a[stk.top()]<w[col])) w[col]=a[stk.top()];
}
if(!stk.empty() && stk.top()==u)ins[u]=0,stk.pop();
}
}
int vis[3003];
bool e[3003][3003];
void dfs(const int u){
if(vis[u]) return;
vis[u]=1;
for(const int v:G[u]){
if(scc[u]!=scc[v] && !e[scc[u]][scc[v]]) ++in[scc[v]],e[scc[u]][scc[v]]=1;
dfs(v);
}
}
int main(){
scanf("%d%d",&n,&p);
memset(a,-1,sizeof a);
for(int x,y;p--;)scanf("%d%d",&x,&y),a[x]=y;
scanf("%d",&m);
for(int u,v;m--;)scanf("%d%d",&u,&v),G[u].push_back(v);
for(int i=1;i<=n;i++)if(!dfn[i]) tarjan(i);
for(int i=1;i<=n;i++)if(!vis[i]) dfs(i);
memset(vis,-1,sizeof vis);
for(int i=1;i<=n;i++){
if(a[i]>=0) vis[scc[i]]=0;
else if(a[i]<0 && vis[scc[i]]<0) vis[scc[i]]=i;
}
int ans=0;
for(int i=1;i<=col;i++){
if(!in[i]){
if(vis[i]) return printf("NO\n%d\n",vis[i]),0;
else ans+=w[i];
}
}
printf("YES\n%d\n",ans);
return 0;
}