fjutacm 1911 para construir Conceptos básicos de dibujo (a) antes de la cadena a la estrella, una matriz de deduplicación dinámico

Descripción del problema
que una los puntos M de N son bordes (de número de punto 1 ~ N) conectado a la salida en orden ascendente dar, entonces no es Q veces interrogación, interrogación de entrada cada vez que un número de puntos, y el punto de dígrafo todos los puntos para cada pregunta, cada salida punto asociado sólo una vez, si no hay punto asociado, la salida es nulo.

Entrada
pluralidad de conjuntos de casos de prueba.
La primera línea, la entrada de tres números enteros positivos N, M, Q, N puntos, respectivamente, los bordes M, Q tiempos de interrogación (0 <n <= 10000,0 < M <= 1.000.000, 0 <Q <= 100).

Luego están M filas, cada línea de entrada dos enteros positivos a, b. Se indica un punto a punto numerada número de punto b.

Entonces hay líneas Q, cada introduzca un número entero positivo C, lo que indica una investigación de ese punto.

Todos los datos y respuestas están en el rango de interior int.

Salida
Para cada conjunto de casos de prueba, de acuerdo a las preguntas formuladas, la salida de respuesta

SampleInput
3 2 2
1 2
2 3
1
3
3 4 1
1 3
1 1
1 2
1 3
1
SampleOutput
2
NULL
1
2
3

se enfrentan a problemas chinos, no leen el título. Este movimiento blog para la resolución de problemas y estrellas vector de la cadena pesada se utiliza principalmente antes, tal vez hay otra solución, no hable, me gustaría decir en un comentario, directamente en el código.

#include<vector>
#include<algorithm>
#include<stdio.h>
using namespace std;
const int MAXP=10005;
const int MAXL=1000005;

int first[MAXP];  /// 存放每个点相关的Edge在edge中的位置,大小为点的个数
int flag;   /// 把所有边一个一个往edge[]里塞的时候要用

struct Edge
{
  int to;      /// 该边的终点,起点在first里
  int next;    /// edge[i].next表示第i条边的上一条边在edge数组中的位置
}edge[MAXL];   /// 记录边,大小为边的个数

void init(int n)
{
  flag = 0;
  for (int i=1; i<=n; i++)
    first[i] = -1;
}

void create(int a, int b)
{
  edge[flag].to = b;          /// 在edge[]的flag处记录这条以a为起点的边的终点b
  edge[flag].next = first[a]; /// 这条边的next指向上一个以a为起点的边在edge[]中
                              ///的位置,这样形成一个链表的结构。也就是说,访问
                              ///完某一条边edge[i],我可以根据edge[i].next知道还
                              ///有没有a为起点的边,有的话它在edge[]的哪里,方便
                              ///我们直接去访问;next为-1时就是没边了
  first[a] = flag++;          /// 把指针flag往后推一位
}

int main()
{
  int n, m, q, a, b, i;
  vector<int>gather;    ///之后应题意,排序、去重要用
  while (~scanf("%d%d%d", &n, &m, &q))
  {
    init(n);
    while (m--)
    {
      scanf("%d%d", &a, &b);
      create(a, b);
    }
    while (q--)
    {
      scanf("%d", &a);
      if (first[a] == -1)
        puts("NULL");
      else
      {
        gather.clear();
        for (i=first[a]; i!=-1; i=edge[i].next)/// first[]记录的是以i为起点的最后
    ///一条边在edge[]中的位置,结合上面的注释,为什么这么遍历应该就很好理解了
          gather.push_back(edge[i].to);///一条一条统统压进gather
        
        sort(gather.begin(), gather.end());/// 划重点,vector的参数要传迭代器,而
          ///.begin()和.end()返回的正是指向头和尾的迭代器(我理解成vector的地址)
        
        gather.erase(unique(gather.begin(), gather.end()), gather.end());/// 前面的
        ///unique()把出现过的元素只把一个推到前面,多余的都在后面,返回的是无重
        ///复序列尾部再往后一位的迭代器,.erase()擦去制定位置或制定区间元素(记
        ///得这个时候.size()是会相应减少的,所以外面如果有整型常量,譬如n在记录
        ///数组长度,记得减去被擦去区间的长度,否则小心遍历时出错),这一套操
        ///作实现vector动态数组的去重
        for (i=0; i<(int)gather.size(); i++)
          printf("%d\n", gather[i]); /// 遍历一遍,输出题目要求的答案
      }
    }
  }
  return 0;
}

Se han publicado 19 artículos originales · ganado elogios 0 · Vistas 510

Supongo que te gusta

Origin blog.csdn.net/qq_43317133/article/details/98206659
Recomendado
Clasificación