UVA1327 King's Quest Problem Solution

The author does not have an ac, because it is not bound and not submitted. But submit ac on other OJs to ensure code correctness.

UVA1327 King's Quest Portal

A board problem with strongly connected components .


Ideas:

The girl who can to be liked by the prince and can be married (that is, the list of wizards). Isn't this similar to the strong connected component? The condition is satisfied as long as the girl the prince likes and the prince are in the same strong connected component.

The difference between this question and the board is mainly in the construction of edges and the output of the answer, mainly to talk about these two.

1. Build edges:

  • Build a border between the prince and the girl he likes;

  • Build a border between a girl who can be married and a prince.

These combined topics and ideas are not difficult to understand.

2. Output

Overview: From the girls the prince likes, pick the girls in the same strong connected component as the prince, save them, and output them in ascending order of numbers.

  1. Use forward star or vector to find the girl with direct connection to the prince (the girl the prince likes);

  2. Determine whether the two are in the same strongly connected component;

  3. Use a variable to record the number of girls, and use an array to store the number of girls;

  4. After searching, you can sort the output.


detail:

  1. The number of the girl is guaranteed not to be repeated with the prince, so that the number of the i-th girl is i + n;

  2. If you need to write fast reading and fast writing, an OJ can also use cin and cout;

  3. The data range is 2000005 , the bigger the better .


Code:

(Quick reading and quick writing are also attached here.)

#include<bits/stdc++.h>
using namespace std;

const int maxn = 2000005;
int n;
int cnt, hd[maxn];
struct node{
    
    
   int to, nxt;
}e[maxn * 2];
int tmp, dfn[maxn], low[maxn];
int st[maxn], top;
int co[maxn], col;
int ans[maxn];

int read ()
{
    
    
   int x = 1, s = 0;
   char ch = getchar ();
   while (ch < '0' or ch > '9') {
    
    if (ch == '-') x = -1; ch = getchar ();}
   while (ch >= '0' and ch <= '9'){
    
    s = s * 10 + ch - '0'; ch = getchar ();}
   return x * s;
}

void write (int x)
{
    
    
   if (x == 0) return;
   write (x / 10);
   putchar (x % 10 + '0');
}

void add (int u, int v)
{
    
    
   e[++cnt].to = v;
   e[cnt].nxt = hd[u];
   hd[u] = cnt;
}

void tarjan (int u)
{
    
    
   dfn[u] = low[u] = ++tmp;
   st[++top] = u;
   for (int i = hd[u]; i; i = e[i].nxt)
   {
    
    
   	int v = e[i].to;
   	if (!dfn[v])
   	{
    
    
   		tarjan (v);
   		low[u] = min (low[u], low[v]);	
   	}	
   	else if (!co[v]) low[u] = min (low[u], dfn[v]);
   }	
   if (dfn[u] == low[u])
   {
    
    
   	col++;
   	co[u] = col;
   	while (st[top] != u)
   	{
    
    
   		co[st[top]] = col;
   		top--;
   	}
   	top--;
   }
}

int main ()
{
    
    
   cin >> n;
   for (int i = 1; i <= n; i++)
   {
    
    
   	int k;
   	cin >> k;
   	for (int j = 1; j <= k; j++)
   	{
    
    
   		int v;
   		cin >> v;
   		add (i, v + n);
   	}
   }
   for (int i = 1; i <= n; i++)
   {
    
    
   	int v;
   	cin >> v;
   	add (v + n, i);
   }
   for (int i = 1; i <= n; i++)
   {
    
    
   	if (!dfn[i]) tarjan (i);
   }
   for (int i = 1; i <= n; i++)
   {
    
    
   	int tot = 0;
   	for (int j = hd[i]; j; j = e[j].nxt)
   	{
    
    
   		int v = e[j].to;
   		if (co[i] == co[v]) 
   		{
    
    
   			tot++;
   			ans[tot] = v - n;	
   		}
   	}
   	cout << tot << " ";
   	sort (ans + 1, ans + tot + 1);
   	for (int l = 1; l <= tot; l++)
   	{
    
    
   		cout << ans[l] << " ";
   	} 
   	cout << endl;
   }
   return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324133259&siteId=291194637