1. 程式人生 > >洛谷 #1262. 間諜網路

洛谷 #1262. 間諜網路

題意

間諜掌握著其他一些間諜的資料,可以買通一些間諜,或通過資料抓住一些間諜並獲得他們的資料

問能否成功,最小花費

題解

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