Componentes fuertemente conectados de gráficos dirigidos ------- Galaxy

Las estrellas en la Vía Láctea son vastas, pero solo nos enfocamos en las estrellas más brillantes.
Utilizamos un número entero positivo para representar el brillo de la estrella. Cuanto mayor sea el valor, más brillante será la estrella. El brillo más oscuro de la estrella es 1.
Ahora, para las N estrellas que nos preocupan, se ha determinado la relación relativa entre M y brillo.
Su tarea es encontrar al menos qué tan grande es la suma de los valores de brillo de las N estrellas.
Formato de entrada La
primera línea da dos enteros N y M.
Después de M filas, tres enteros T, A, B en cada fila representan la relación de brillo entre un par de estrellas (A, B). La numeración de las estrellas comienza desde 1.
Si T = 1, el brillo de A y B es igual.

Si T = 2, significa que el brillo de A es menor que el brillo de B.

Si T = 3, significa que el brillo de A no es menor que el brillo de B.

Si T = 4, significa que el brillo de A es mayor que el brillo de B.

Si T = 5, significa que el brillo de A no es mayor que el brillo de B.
Formato de
salida Emite un número entero para indicar el resultado.
Si no hay solución, se genera -1.
Rango de datos
N≤100000, M≤100000N≤100000, M≤100000
Muestra de entrada:
5 7
1 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1

Salida de muestra:
11

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010, M = 600010;
typedef long long LL;
int n, m;
int h[N], hs[N], e[M], w[M], ne[M], idx;
int dfn[N], low[N], timestamp;
int stk[N], top;
bool in_stk[N];
int id[N], scc_cnt, Size[N];
int dist[N];
void add(int h[], int a, int b, int c){
 e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}
void tarjan(int u){
 dfn[u] = low[u] = ++timestamp;
 stk[++ top] = u, in_stk[u] = true;
  for (int i = h[u]; ~i; i = ne[i]){
      int j = e[i];
   if (!dfn[j]){
    tarjan(j);
    low[u] = min(low[u], low[j]);
   } 
  else  if (in_stk[j])    low[u] = min(low[u], dfn[j]);
 }
  if  (dfn[u] == low[u]){
  ++ scc_cnt;
  int y;
  do{
   y = stk[top --];
   in_stk[y] = false;
   id[y] = scc_cnt;
   Size[scc_cnt] ++;
  }while(y != u);
 }
}
int main(){
 scanf("%d%d", &n, &m);
 memset(h, -1, sizeof h);
 memset(hs, -1, sizeof hs);
  for (int i = 1; i <= n; i ++)   add(h, 0, i, 1);
  while(m --){
  int t, a, b;
  scanf("%d%d%d", &t, &a, &b);
  if (t == 1)   add(h, a, b, 0), add(h, b, a, 0);
  else if (t == 2)   add(h, a, b, 1);
  else if (t == 3)   add(h, b, a, 0);
  else if (t == 4)   add(h, b, a, 1);
  else      add(h, a, b, 0);
 }
  tarjan(0);
  bool success = true;
 for (int i = 0; i <= n; i ++){
  for (int j = h[i]; ~j; j = ne[j]){
   int k = e[j];
   int a = id[i], b = id[k];
   if (a == b){
    if (w[j] > 0){
     success = false;
     break;
    }
   }
   else   add(hs, a, b, w[j]);
  }
  if (!success)    break;
 }
  if (!success)   puts("-1");
 else{
  for (int i = scc_cnt; i; i --){
   for (int j = hs[i]; ~j; j = ne[j]){
    int k = e[j];
    dist[k] = max(dist[k], dist[i] + w[j]);
   }
  }
    LL res = 0;
  for (int i = 1; i <= scc_cnt; i ++)   res += (LL)dist[i] * Size[i];
  cout << res << endl;
 }
  return 0;
}
164 artículos originales publicados · Me gusta 112 · Visitantes 6755

Supongo que te gusta

Origin blog.csdn.net/qq_45772483/article/details/105610593
Recomendado
Clasificación