题意
间谍掌握着其他一些间谍的资料,可以买通一些间谍,或通过资料抓住一些间谍并获得他们的资料
问能否成功,最小花费
题解
Tarjan缩点,以环中最小的权值作为大点的权值
调试记录
数组开小了!?
#include <cstdio>
#include <stack>
#include <cstring>
#include <algorithm>
#define maxn 10005
#define INF 0x3f3f3f3f
using namespace std;
struct node{
int to, next;
}e[maxn << 1];
int tot = 0, head[maxn];
void addedge(int u, int v){e[++tot] = (node){v, head[u]}; head[u] = tot;}
stack <int> s;
int dfn[maxn], low[maxn], Index = 0, Ctot = 0;
bool vis[maxn]; int color[maxn], val[maxn], cost[maxn];
void Tarjan(int cur){
dfn[cur] = low[cur] = ++Index;
vis[cur] = true;
s.push(cur);
for (int i = head[cur]; i; i = e[i].next){
if (!dfn[e[i].to]){
Tarjan(e[i].to);
low[cur] = min(low[cur], low[e[i].to]);
}
else if (vis[e[i].to]) low[cur] = min(low[cur], low[e[i].to]);
}
if (dfn[cur] == low[cur]){
Ctot++; val[Ctot] = INF;
while (s.top() != cur){
vis[s.top()] = false;
color[s.top()] = Ctot;
val[Ctot] = min(val[Ctot], cost[s.top()]);
s.pop();
}
vis[s.top()] = false;
color[s.top()] = Ctot;
val[Ctot] = min(val[Ctot], cost[s.top()]);
s.pop();
}
}
struct Q{
int u, v;
}q[maxn];
int in[maxn];
int n, p, r;
int main(){
scanf("%d%d", &n, &p);
memset(cost, 0x3f, sizeof cost);
for (int id, i = 1; i <= p; i++){
scanf("%d", &id); scanf("%d", &cost[id]);
}
scanf("%d", &r);
for (int i = 1; i <= r; i++){
scanf("%d%d", &q[i].u, &q[i].v);
addedge(q[i].u, q[i].v);
}
for (int i = 1; i <= n; i++)
if (!dfn[i] && cost[i] != INF) Tarjan(i);
for (int i = 1; i <= n; i++)
if (!dfn[i]){
printf("NO\n%d\n", i);
return 0;
}
memset(e, 0, sizeof e);
memset(head, 0, sizeof head);
tot = 0;
for (int i = 1; i <= r; i++)
if (color[q[i].u] != color[q[i].v]) addedge(color[q[i].u], color[q[i].v]), in[color[q[i].v]]++;
int ans = 0;
for (int i = 1; i <= Ctot; i++)
if (!in[i]) ans += val[i];
printf("YES\n%d\n", ans);
return 0;
}