11112: 【原1112】二哥发论文
题目
题目描述
author: Cheng Chen 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1112
Description
二哥是一个热爱科研的人。前几天二哥的一篇论文被某个国际顶级会议录用,今天,二哥要在学校里举行一个学术问答会,接受同学们的提问。
在交大,有n个人对二哥的研究方向感兴趣(以1-n编号).他们并不互相认识,但是如果甲认识乙那么乙一定认识甲. 这n个人中有k个人得知二哥要举行问答会。二哥并不是随便接受提问的,他会在排队提问的人当中挑选学术水平最高的人接受提问。而提问完之后,这位同学会立刻去找他认识的并对二哥的研究方向感兴趣的人,而这些人也会第一时间赶到现场排队提问。现在二哥想知道提问的同学是按什么顺序提问的。
Input Format
第一行包含了两个整数n,k(k<=n<=1000). 接下来一行有n个整数,表示每个同学的学术水平(<=100000).每个同学的学术水平各不相同. 接下来一行有k个整数,表示一开始就知道二哥的讲座的同学的标号(从1开始). 最后是一个n*n的矩阵,若第i行第j列是1则表示标号为i的同学和标号为j的同学认识,否则为不认识。
Output Format
每行一个整数,按顺序表示提问的同学的编号.
Sample Input
5 2
76708 24510 69869 85113 61546
3 4
0 1 1 1 1
1 0 1 0 1
1 1 0 0 0
1 0 0 0 0
1 1 0 0 0
Sample Output
4
1
3
5
2
FineArtz's solution
/* 二哥发论文 */
#include <iostream>
using namespace std;
class Heap{
private:
int a[1005] = {0};
int b[1005] = {0};
int heapsize = 0;
void swap(int x, int y){
int t = a[x];
a[x] = a[y];
a[y] = t;
t = b[x];
b[x] = b[y];
b[y] = t;
}
public:
void siftup(int i){
while (i != 1){
if (a[i] > a[i / 2]){
swap(i, i / 2);
i /= 2;
}
else
break;
}
}
void siftdown(){
int i = 2;
while (i <= heapsize){
if (i + 1 <= heapsize && a[i] < a[i + 1])
++i;
if (a[i] > a[i / 2]){
swap(i, i / 2);
i *= 2;
}
else
break;
}
}
void insert(int x, int y){
a[++heapsize] = x;
b[heapsize] = y;
siftup(heapsize);
}
void remove(){
swap(1, heapsize);
--heapsize;
siftdown();
}
int getMax(){
return b[1];
}
bool empty(){
return (heapsize == 0);
}
};
Heap heap;
int n, k;
int a[1005], m[1005][1005];
bool v[1005] = {false};
int main(){
cin >> n >> k;
for (int i = 1; i <= n; ++i){
cin >> a[i];
}
for (int i = 1; i <= k; ++i){
int t;
cin >> t;
heap.insert(a[t], t);
v[t] = true;
}
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= n; ++j){
cin >> m[i][j];
}
}
while (!heap.empty()){
int x = heap.getMax();
cout << x << endl;
heap.remove();
for (int i = 1; i <= n; ++i)
if (m[x][i] && !v[i]){
heap.insert(a[i], i);
v[i] = true;
}
}
return 0;
}
ligongzzz's solution
#include "iostream"
#include "cstring"
using namespace std;
template <class T>
class mVector {
T** vector_data = nullptr;
unsigned int size = 0;
unsigned int capacity = 0;
public:
//构造函数
mVector() = default;
mVector(unsigned int _size) :size(_size) {
capacity = _size * 2;
vector_data = new T * [capacity] {nullptr};
}
mVector(unsigned int _size, const T& val) :size(_size) {
capacity = _size * 2;
vector_data = new T * [capacity] {nullptr};
for (unsigned int i = 0; i < _size; ++i)
vector_data[i] = new T(val);
}
mVector(const mVector<T>& _vector) :size(_vector.size), capacity(_vector.capacity) {
vector_data = new T * [capacity] {nullptr};
for (int i = 0; i < size; ++i)
vector_data[i] = new T(*_vector.vector_data[i]);
}
//析构函数
~mVector() {
for (unsigned int i = 0; i < size; ++i)
delete vector_data[i];
delete[] vector_data;
}
//迭代器
class iterator {
T** pos = nullptr;
friend iterator mVector<T>::begin();
friend iterator mVector<T>::end();
friend void mVector<T>::erase(const iterator& val);
public:
iterator() = default;
iterator(const iterator& other) {
pos = other.pos;
}
iterator& operator++() {
++pos;
return *this;
}
iterator operator++(int) {
iterator temp(*this);
++pos;
return temp;
}
iterator& operator--() {
--pos;
return *this;
}
iterator operator--(int) {
iterator temp(*this);
--pos;
return temp;
}
bool operator==(const iterator& other) const {
return pos == other.pos;
}
bool operator!=(const iterator& other) const {
return pos != other.pos;
}
iterator& operator=(const iterator& other) {
pos = other.pos;
return *this;
}
T& operator*() const {
return **pos;
}
};
//增加元素
void push_back(const T& val) {
if (size < capacity)
vector_data[size++] = new T(val);
else {
T** temp_data = new T * [(capacity + 1) * 2]{ nullptr };
for (unsigned int i = 0; i < size; ++i)
temp_data[i] = vector_data[i];
temp_data[size++] = new T(val);
capacity = (capacity + 1) * 2;
delete[] vector_data;
vector_data = temp_data;
}
}
//删除末尾
void pop_back() {
delete vector_data[--size];
vector_data[size] = nullptr;
}
//清空
void clear() {
for (unsigned int i = 0; i < size; ++i) {
delete vector_data[i];
vector_data[i] = nullptr;
}
size = 0;
}
//删除
void erase(const iterator& val) {
delete* val.pos;
for (auto p = val.pos; p != vector_data + size - 1; ++p)
* p = *(p + 1);
--size;
vector_data[size] = nullptr;
}
//重载运算符
T& operator[](const unsigned int& pos) {
return *vector_data[pos];
}
iterator begin() {
iterator temp;
temp.pos = vector_data;
return temp;
}
iterator end() {
iterator temp;
temp.pos = vector_data + size;
return temp;
}
};
template <class T>
class myPriorityQueue {
mVector<T> queueData;
unsigned int sizeOfQueue = 0;
bool(*cmp)(T a, T b) = [](T a, T b) {return a < b; };
//向下过滤
void percolateDown(unsigned int pos) {
while (pos * 2 <= sizeOfQueue) {
if (pos * 2 + 1 > sizeOfQueue) {
//交换
if (cmp(queueData[pos * 2], queueData[pos])) {
auto temp = queueData[pos * 2];
queueData[pos * 2] = queueData[pos];
queueData[pos] = temp;
}
break;
}
else {
bool minNum = cmp(queueData[pos * 2 + 1], queueData[pos * 2]);
if (cmp(queueData[pos * 2 + minNum], queueData[pos])) {
auto temp = queueData[pos * 2 + minNum];
queueData[pos * 2 + minNum] = queueData[pos];
queueData[pos] = temp;
pos = pos * 2 + minNum;
}
else break;
}
}
}
public:
//构建
myPriorityQueue() {
queueData.clear();
queueData.push_back(*new T);
sizeOfQueue = 0;
}
//compare函数返回父结点a与孩子结点b的关系正确与否
myPriorityQueue(bool(*compare)(T a, T b)) :cmp(compare) {
queueData.clear();
queueData.push_back(*new T);
sizeOfQueue = 0;
}
//根据数组建立堆
void buildHeap(T* eleData, unsigned int eleNum) {
queueData.clear();
sizeOfQueue = eleNum;
queueData.push_back(*new T);
for (unsigned int i = 1; i <= eleNum; i++)
queueData.push_back(eleData[i - 1]);
//向下过滤
for (unsigned int pos = eleNum / 2; pos > 0; pos--)
percolateDown(pos);
}
//判断是否空
bool empty() {
return sizeOfQueue == 0;
}
//返回队列大小
auto size() {
return sizeOfQueue;
}
//入队
void push(const T& input) {
sizeOfQueue++;
queueData.push_back(input);
//向上过滤
for (auto i = sizeOfQueue; i > 1; i = i / 2) {
//判断是否比父结点更小
if (cmp(queueData[i], queueData[i / 2])) {
//交换
auto temp = queueData[i];
queueData[i] = queueData[i / 2];
queueData[i / 2] = temp;
}
else break;
}
}
//队列最前
T top() {
return queueData[1];
}
//出队
T pop() {
auto temp = queueData[1];
queueData[1] = queueData[sizeOfQueue--];
queueData.pop_back();
percolateDown(1);
return temp;
}
};
class student {
public:
int code = 0;
int val = 0;
};
bool map_data[1009][1009] = { 0 };
student val_data[1009];
bool visited[1009] = { 0 };
myPriorityQueue<student> queue_data([](student a, student b) {return a.val > b.val; });
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, k;
cin >> n >> k;
for (int i = 0; i < n; ++i) {
val_data[i].code = i;
cin >> val_data[i].val;
}
for (int i = 0; i < k; ++i) {
int temp;
cin >> temp;
visited[temp - 1] = true;
queue_data.push(val_data[temp - 1]);
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
cin >> map_data[i][j];
}
}
while (!queue_data.empty()) {
auto temp = queue_data.top();
queue_data.pop();
cout << temp.code + 1 << " ";
for (int i = 0; i < n; ++i) {
if (map_data[temp.code][i] && !visited[i]) {
queue_data.push(val_data[i]);
visited[i] = true;
}
}
}
return 0;
}
Neight99's solution
#include <iostream>
using namespace std;
struct student {
int num;
int knowledge;
bool operator<(const student &right) const {
return knowledge < right.knowledge;
}
};
const int maxN = 1e3 + 10;
int interest[maxN] = {0}, n, k;
bool rec[maxN][maxN] = {0}, inque[maxN] = {0};
student stu[maxN] = {0};
template <class Type>
class priorityQueue {
private:
int currentSize;
Type *array;
int maxSize;
void doubleSpace();
void buildHeap();
void percolateDown(int);
public:
priorityQueue(int capacity = maxN);
priorityQueue(const Type *data, int size);
~priorityQueue();
bool isEmpty() const;
void enQueue(const Type &x);
Type deQueue();
Type getHead() const;
};
template <class Type>
priorityQueue<Type>::priorityQueue(int capacity)
: maxSize(capacity), currentSize(0) {
array = new Type[capacity];
}
template <class Type>
priorityQueue<Type>::priorityQueue(const Type *data, int size)
: maxSize(size + 10), currentSize(size) {
array = new Type[maxSize];
for (int i = 0; i < size; i++) {
array[i + 1] = data[i];
}
buildHeap();
}
template <class Type>
priorityQueue<Type>::~priorityQueue() {
delete[] array;
}
template <class Type>
bool priorityQueue<Type>::isEmpty() const {
return currentSize == 0;
}
template <class Type>
Type priorityQueue<Type>::getHead() const {
return array[1];
}
template <class Type>
void priorityQueue<Type>::enQueue(const Type &x) {
if (currentSize == maxSize - 1) {
// doubleSpace();
}
int hole = ++currentSize;
for (; hole > 1 && x < array[hole / 2]; hole /= 2) {
array[hole] = array[hole / 2];
}
array[hole] = x;
}
template <class Type>
Type priorityQueue<Type>::deQueue() {
Type minItem;
minItem = array[1];
array[1] = array[currentSize--];
percolateDown(1);
return minItem;
}
template <class Type>
void priorityQueue<Type>::percolateDown(int hole) {
int child;
Type tmp = array[hole];
for (; hole * 2 <= currentSize; hole = child) {
child = hole * 2;
if (child != currentSize && array[child + 1] < array[child]) {
child++;
}
if (array[child] < tmp) {
array[hole] = array[child];
} else {
break;
}
}
array[hole] = tmp;
}
template <class Type>
void priorityQueue<Type>::doubleSpace() {
Type *tmp = array;
maxSize *= 2;
array = new Type[maxSize];
for (int i = 0; i < currentSize; i++) {
array[i] = tmp[i];
}
delete[] tmp;
}
template <class Type>
void priorityQueue<Type>::buildHeap() {
for (int i = currentSize / 2; i > 0; i--) {
percolateDown(i);
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
priorityQueue<student> que;
cin >> n >> k;
for (int i = 1; i <= n; i++) {
stu[i].num = i;
cin >> stu[i].knowledge;
stu[i].knowledge = -stu[i].knowledge;
}
for (int i = 0; i < k; i++) {
int temp;
cin >> temp;
que.enQueue(stu[temp]);
inque[temp] = 1;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> rec[i][j];
}
}
while (!que.isEmpty()) {
int temp = que.deQueue().num;
cout << temp << '\n';
for (int i = 1; i <= n; i++) {
if (!inque[i] && rec[temp][i]) {
que.enQueue(stu[i]);
inque[i] = 1;
}
}
}
return 0;
}
yyong119's solution
#include <cstdio>
#include <queue>
using namespace std;
int index[100005], relation[1005][1005], level[1005];
bool known[1005];
priority_queue<int> pri_que;
int main() {
int n, k; scanf("%d%d", &n, &k);
for (int i = 1; i <= n; ++i) {
scanf("%d", &level[i]);//level[i]第i个人的知识水平
index[level[i]] = i;//知识水平为level[i]的人的编号
}
for (int i = 1; i <= k; ++i) {
int id; scanf("%d", &id);
known[id] = true; pri_que.push(level[id]);
}
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
scanf("%d", &relation[i][j]);
while (!pri_que.empty()) {
int asked_index = index[pri_que.top()];
printf("%d\n", asked_index);
pri_que.pop();
for (int i = 1; i <= n; ++i)
if (relation[i][asked_index] && !known[i]) {
pri_que.push(level[i]);
known[i] = true;
}
}
return 0;
}