P1262 间谍网络

#include <cstdio>
#include <bits/stdc++.h>
using namespace std;

const int N = 3005, M = 8005;

stack<int> st;
int n,p,pr[N],f[N];
int head[N], tot = 0, dfn[N], low[N], num = 0, co[N], col = 0;

struct EDGE {
    int to, nxt;
} e[M];

void add(int u, int v) {
    e[++tot].to = v;
    e[tot].nxt = head[u];
    head[u] = tot;
}

void Tarjan(int u) {
    dfn[u] = low[u] = ++num;
    st.push(u);

    for (int i = head[u]; i; i = e[i].nxt) {
        int v = e[i].to;

        if (dfn[v] == 0) {
            Tarjan(v);
            low[u] = min(low[u], low[v]); //
        } else if (co[v] == 0) {
            low[u] = min(low[u], dfn[v]); //
        }
    }

    if (low[u] == dfn[u]) { //
        co[u] = ++col;
        f[col]=pr[u];
        
        while (st.top() != u) {
            co[st.top()] = col;
            f[col]=min(f[col],pr[st.top()]);
            
            st.pop();
        }

        st.pop();
    }

}

int ans1, ans2, vis[N][N] = {0};

void count() {

    for (int i = 1; i <= n; i++) {
        for (int j = head[i]; j; j = e[j].nxt) {
            if (co[e[j].to] != co[i] && vis[i][e[j].to] == 0) { //
                vis[i][e[j].to] = 1;
                vis[0][co[e[j].to]]++;
                vis[co[i]][0]++;
            }
        }
    }
}

int v[N];
void DFS( int x ){                               //特殊处理
    v[x] = 1;
    for ( int i = head[x]; i; i = e[i].nxt )
        if ( !v[e[i].to] ) DFS( e[i].to );
}

int main() {
    cin >> n>>p;
    
    for ( int i = 1; i <= n; ++i ) pr[i] = INT_MAX;
    for ( int i = 1; i <= p; ++i ) {int x,y; scanf( "%d%d", &x, &y ), pr[x] = y;}
    int r;
    scanf( "%d", &r );
    for ( int i = 1; i <= r; ++i )  {int x,y; scanf( "%d%d", &x, &y ), add( x, y );}

    
    for ( int i = 1; i <= n; ++i ) if ( pr[i] < INT_MAX && !v[i] ) DFS( i );////特殊处理
    for ( int i = 1; i <= n; ++i ) if ( !v[i] ){ printf( "NO\n%d\n", i ); return 0; }////特殊处理
    for ( int i = 1; i <= n; ++i ) if ( !dfn[i] ) Tarjan( i );
    
    count();
/*
    for (int i = 1; i <= col; i++) {
        ans1 += (vis[0][i] == 0);
        ans2 += (vis[i][0] == 0);
    }
*/
     
    int ans=0; 
    for ( int i = 1; i <= col; ++i ) if ( !vis[0][i] ) ans += f[i];
    printf( "YES\n%d\n", ans );
    
   // cout << ans1 ;//<< endl << ((col == 1) ? 0 : max(ans1, ans2)) << endl;

    return 0;
}

 

posted @ 2023-09-17 16:00  JMXZ  阅读(22)  评论(0)    收藏  举报