P1262 spy network

Keywords: Algorithm

Title Description

National security is in high crisis due to the infiltration of foreign spies. If A spies have criminal evidence of B spies in their hands, A can reveal them.B. Some spies take bribes and give them a certain amount of dollars so they are willing to hand over all the information they have in their hands. So if we can buy some spies, we might be able to control every member of the spy network. Because once we arrest a spy, all the information in his hands will belong to us, so it's possible to arrest a new oneSpy, get new information.

Our anti-spy agency provided a copy of the information, including all known bribery spies and the exact amount they were willing to accept. We also know which spies are in the hands of which spies. Suppose there are NN spies (nn does not exceed 30003000), each of which is identified by an integer of 11 to 300030003.

Please use this information to determine if it is possible for us to control all the spies and, if possible, figure out the minimum amount of money we need to pay. Otherwise, export one of the spies that cannot be controlled.

Input Format

The first row has only one integer nn.

The second line is the integer P P. Indicates the number of people willing to be bought, 1\le ple N1 < p < n.

The next pp line has two integers, the first is the number of a spy who is willing to be bought, and the second is the amount he will be bought. This number does not exceed 2000020000.

The following row has only one integer R r, 1\le rle80001 < R < 8000. Then the r r row, two positive integers per row, represents a pair of numbers (A, B)(A,B), and the AA spy has evidence of a BB spy.

Output Format

If you can control all the spies, the first line outputs YES and the minimum amount of bribes to be paid on the second line. Otherwise, you output NO and the smallest number of spies in the second line outputs that cannot be controlled.

input
3
2
1 10
2 100
2
1 3
2 3

Output:
YES
110
/*
* There are two situations with this question
* One is that if there are spies who neither bribe him directly nor expose him through other spies, there is no solution to the problem and we mark him as we traverse
* Then enumerate from small to large, output whenever there is no tag and exit
* 
* Second, all spies can be exposed or bribed directly or indirectly. There are also two situations. First, if there is no ring, then capital is bribery.
* If there are no properly paid spies but rings, then the money is the least needed to bribe the spies in that ring. If the rings are reduced to one
* Point, then this is all the first case (the ring described above should be a strongly connected component in the diagram)
*/


#include <iostream>
#include <algorithm>
using namespace std;

const int INF = 0x3fffffff; //Indicate the amount needed by an infinite number of spies that cannot be exposed
const int maxn = 3005;  //Maximum number of vertices
const int maxm = 8005; //Maximum number of polygons

//Chain Forward Star Storage Edge
int head[maxn], cnt1;
int val[maxn]; //Weight of each node
struct edge
{
	int to;
	int next;
}e[maxm];

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

//Create a new diagram section
int cnt2;  //Count the number of strongly connected components
int cap[maxn];  //Sequence number of the strongly connected component where each node is located
int sum[maxn];  //sum[i] denotes the point weight of strongly connected components
int inDegree[maxn];  //inDegree[i] represents the degree of penetration of strongly connected components

//tarjan section
int dfn[maxn]; //Time stamp array, dfn[i] denotes the order in which node I is traversed
int low[maxn];  //Minimum ordinal array
int ind; //time stamp
int _stack[maxn], top;  //The stack and the top pointing to the top element of the stack
bool instack[maxn];  //Determine if vertices are on the stack

void tarjan(int x)
{
	dfn[x] = low[x] = ++ind;
	_stack[++top] = x;
	instack[x] = true;

	for (int i = head[x]; i; i = e[i].next)
	{
		int v = e[i].to;
		if (!dfn[v]) //If not already visited, recursively
		{
			tarjan(v);
			low[x] = min(low[x], low[v]);
		}
		else if (instack[v])  //Has been visited to determine if it is on the stack, that is, whether it is looped
		{
			low[x] = min(low[x], dfn[v]);
		}
	}

	//If the node is the root node in the search tree, set the sequence number of the strongly connected components of all the nodes in the stack to the same, and find the minimum value
	if (dfn[x] == low[x])
	{
		cnt2++;
		while (_stack[top + 1] != x)
		{
			cap[_stack[top]] = cnt2;
			instack[_stack[top]] = false;
			sum[cnt2] = min(sum[cnt2], val[_stack[top]]);
			top--;
		}
	}
}

int main()
{
	//Initialization of Node Weight Array val and Strong Connected Component Weight Array sun
	fill(val, val + maxn, INF);
	fill(sum, sum + maxn, INF);

	int n; //Number of Spy
	cin >> n;

	int p; //Number of people willing to be bought
	int a, b; //The number of the spy who is willing to be bought, the amount of money bought
	cin >> p;
	for (int i = 1; i <= p; i++)
	{
		cin >> a >> b;
		val[a] = b;
	}

	int r; //r-line buyout relationship
	cin >> r;
	for (int i = 1; i <= r; i++)
	{
		cin >> a >> b;
		add(a, b);
	}

	for (int i = 1; i <= n; i++)
	{
		if (!dfn[i] && val[i] != INF) //If it has not been traversed and can be purchased
			tarjan(i);
	}

	for (int i = 1; i <= n; i++)
	{
		if (!dfn[i])  //Not traversed after tarjan, meaning it cannot be bought directly or indirectly
		{
			cout << "NO" << endl << i;
			return 0;
		}
	}

	//Traverse all edges of the original graph, adding 1 to the input strongly connected component if the nodes at both ends of the edge are in different strongly connected components
	for (int i = 1; i <= n; i++)
	{
		for (int j = head[i]; j; j = e[j].next)
		{
			int v = e[j].to;
			if (cap[i] != cap[v])
			{
				inDegree[cap[v]]++;
			}
		}
	}
	int ans = 0;
	//Traverse through all strongly connected components, if the degree of entry is 0, plus their sum values
	for (int i = 1; i <= cnt2; i++)
	{
		if (inDegree[i] == 0)
			ans += sum[i];
	}
	cout << "YES" << endl << ans;
}

Posted by gregsmith on Thu, 07 Oct 2021 09:42:17 -0700