洛谷 #1262. 間諜網路
阿新 • • 發佈:2018-12-22
題意
間諜掌握著其他一些間諜的資料,可以買通一些間諜,或通過資料抓住一些間諜並獲得他們的資料
問能否成功,最小花費
題解
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;
}