forked from chr4ss1/SPOJ
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRPLA.cpp
More file actions
139 lines (112 loc) · 3.11 KB
/
RPLA.cpp
File metadata and controls
139 lines (112 loc) · 3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <iostream>
#include <algorithm>
#include <fstream>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <stdio.h>
using namespace std;
// this is completely related to I/O and has nothing to do with problem itself.
#define MAX_CHUNK_SIZE 65536
char arr[10000000] = {0};
char *ptr = arr;
// I wrote this custom function in order to get
// better running times in SPOJ.
// This can take your 5 seconds to 1 seconds with big INPUT/OUTPUT :)
void parse_data()
{
//FILE * pFile;
//pFile = fopen ( "C:\\Intel\\test_case.txt" , "rb" );
int c, j;
char *ptr = arr;
// read data into buffer!
while((c = fread(ptr, 1, MAX_CHUNK_SIZE, stdin))>0)
ptr += MAX_CHUNK_SIZE;
// reset ptr to beginning.
ptr = arr;
}
// A simple inline function that can extract integer from buffer.
int extract_int()
{
// skip all stupid whitespaces.
while(*ptr == 13 || *ptr == 10 || *ptr == ' ') ptr++;
int wtf = strtol(ptr, 0, 0);
// skip the integer
while(*ptr >= '0' && *ptr <= '9') ptr++;
return wtf;
}
// problem specific
#define MAX_EMPLOYEES 1000
#define MAX_EDGES 10000
int T; // testcases
int N; // number of employees
int R; // number of relations
int R1, R2; // R1 < R2
int cur_rank;
int scenario;
struct employee
{
int id;
int incoming_edges;
int edges[MAX_EDGES];
int edge_count;
bool processed;
};
employee employees[MAX_EMPLOYEES];
int main()
{
parse_data();
T = extract_int();
scenario = 1;
while(T--){
N = extract_int();
R = extract_int();
for(int j = 0; j < N; j++){
employees[j].id = j;
employees[j].edge_count = 0;
employees[j].incoming_edges = 0;
employees[j].processed = false;
}
for(int r = 0; r < R; r++){
R1 = extract_int();
R2 = extract_int();
employees[R2].edges[employees[R2].edge_count] = R1;
employees[R2].edge_count++;
employees[R1].incoming_edges += 1;
}
// scan all employees that have zero incoming edges.
// they must be "roots" aka rank 0 candidates.
cur_rank = 1;
vector<int> rank_candidates;
vector<int> next_level;
for(int j = 0; j < N; j++){
if(!employees[j].incoming_edges)
rank_candidates.push_back(j);
}
// start the actual algorithm that takes care of ranking.
// the idea is simple.
// we start with nodes that have no incoming edges to them,
// we call them "root" nodes. by definition, they have to be "root" ones.
printf("Scenario #%d:\n", scenario++);
while(rank_candidates.size() > 0){
sort(rank_candidates.begin(), rank_candidates.end());
next_level.clear();
for(int w = 0; w < rank_candidates.size(); w++){
printf("%d %d\n", cur_rank, rank_candidates[w]);
employees[rank_candidates[w]].processed = true;
for(int child = 0; child < employees[rank_candidates[w]].edge_count; child++){
if(!employees[employees[rank_candidates[w]].edges[child]].processed){
employees[employees[rank_candidates[w]].edges[child]].incoming_edges -= 1;
if(!employees[employees[rank_candidates[w]].edges[child]].incoming_edges){
next_level.push_back(employees[rank_candidates[w]].edges[child]);
}
}
}
}
cur_rank++;
rank_candidates = next_level;
}
}
return 0;
}