Tarjan punto de contracción [USACO5.3] Campus Red Red de Escuelas (Valle de Los P2746)

[USACO5.3] Campus Red Red de Escuelas

título Descripción

Algunas escuelas incluso en una red de ordenadores. Esas escuelas han llegado a un acuerdo: cada escuela dará algún otro software de distribución de la escuela (en adelante, "la recepción de las escuelas"). Tenga en cuenta que la lista incluso si la escuela B en la lista de distribución A, A no es necesariamente en la década de B-escolares.

¿Quieres escribir un programa para calcular, según el acuerdo, con el fin de hacer que la red todas las escuelas utilizan el nuevo software, nuevas escuelas deben aceptar un número mínimo de copias del Software (subtareas A). Por otra parte, quisimos determinar a través de una escuela para enviar cualquier nuevo software, que será distribuido a todas las escuelas de la red. Para realizar esta tarea, es posible que tenga que ampliar la escuela para recibir las listas de nuevos miembros. Calcule el mínimo necesario aumentar el número de extensiones que nosotros no importa a qué escuela enviar nuevo software hace, alcanzará todas las escuelas restantes (subtareas B). Una extensión es la introducción de un nuevo miembro en la escuela recibe una lista de la escuela.

Formato de entrada

La primera línea del archivo de entrada comprende un número entero positivo n, el número de red de la escuela. Escuelas identificadas por los primeros números enteros positivo n.

A continuación, cada línea representa una lista recepción de la línea escuela N (lista de distribución), la fila i + 1-i incluye la recepción de un identificador de la escuela escuela. Cada lista termina con 0, 0 lista vacía una sola representación.

Formato de salida

Su programa debe salida dos líneas en el archivo de salida.

La primera línea debe incluir un número entero positivo, una solución de subtarea figura.

La segunda fila debe contener un número entero no negativo, solución B subtarea figura.


Esta pregunta es la cuestión de la plantilla comparativo Tarjan encogimiento puntos, pero el punto más importante es comprender el DAG para convertirse en un gráfico fuertemente conectado, y para elevar el número de lados es el grado de penetración y el número de puntos es 0 0 el número máximo de puntos;

código:

#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=20010;
const int M=1000100;
const LL mod=100000000;
int dfn[N],low[N],tot,head[N],cnt,n,sta[N],top,fa[N],in[N],out[N],sum;
vector<int>R[N];
bool vis[N],ma[N][N];
struct Node{
	int to,nex;
}edge[M];
void add(int p,int q){
	edge[cnt].to=q;
	edge[cnt].nex=head[p];
	head[p]=cnt++;
}
void Tarjan(int p){
	dfn[p]=low[p]=++tot;
	if(!vis[p]) vis[p]=true,sta[++top]=p;
	for(int i=head[p];~i;i=edge[i].nex){
		int q=edge[i].to;
		if(!dfn[q]){
			Tarjan(q);
			low[p]=min(low[p],low[q]);
		}
		else if(vis[q]) low[p]=min(low[p],dfn[q]);
	}
	if(dfn[p]==low[p]){
		sum++;//总点数 
		fa[p]=p;
		vis[p]=false;
		while(sta[top]!=p){
			vis[sta[top]]=false;
			fa[sta[top]]=p;
			top--;
		}
		top--;
	}
}
int main(){
	memset(head,-1,sizeof(head));
	cin>>n;
	for(int i=1;i<=n;i++){
		int q;
		while(1){
			scanf("%d",&q);
			if(q==0) break;
			add(i,q);
			R[i].push_back(q);
		}
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i]) Tarjan(i);
	}
	for(int i=1;i<=n;i++){
		for(int j=0;j<R[i].size();j++){
			if(fa[i]!=fa[R[i][j]]&&!ma[fa[i]][fa[R[i][j]]]){
				ma[fa[i]][fa[R[i][j]]]=true;
				in[fa[R[i][j]]]++;
				out[fa[i]]++;
			}
		}
	}
	int ans1=0,ans2=0;
	for(int i=1;i<=n;i++){
		if(fa[i]==i&&in[i]==0) ans1++;
		if(fa[i]==i&&out[i]==0) ans2++;
	}
	if(sum==1) cout<<1<<endl<<0<<endl;
	else cout<<ans1<<endl<<max(ans1,ans2)<<endl;
    return 0;
}
Publicados 264 artículos originales · alabanza won 46 · Vistas a 10000 +

Supongo que te gusta

Origin blog.csdn.net/qq_44291254/article/details/104967069
Recomendado
Clasificación