洛谷 #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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章