fjutacm 1911 to build Drawing Basics (a) before the chain to the star, a dynamic array deduplication

Problem Description
give you an M N points are edges (from point number 1 ~ N) connected to the output in ascending order, then there is Q times interrogation, interrogation input each time a number of points, and the point of digraph All points for each inquiry, each associated point output only once, if no associated point, the output is NULL.

Input
plurality of sets of test cases.
The first line, the input three positive integers N, M, Q, N points, respectively, edges M, Q interrogation times (0 <N <= 10000,0 < M <= 1000000, 0 <Q <= 100).

Then there are M rows, each line of input two positive integers a, b. It indicates a point to point numbered point number b.

Then there are Q lines, each enter a positive integer C, indicating an inquiry that point.

All data and answers are in the range of int inside.

Output
For each set of test cases, according to the questions asked, the answer output

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

Chinese face problems, do not read the title. This blog go to the stars and vector heavy chain problem solving is mainly used before, maybe there are other solution, do not talk, I would like to say in a comment, directly on the code.

#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;
}

Published 19 original articles · won praise 0 · Views 510

Guess you like

Origin blog.csdn.net/qq_43317133/article/details/98206659