Skip to content

Commit 5d95fa0

Browse files
committed
add advance 1175
1 parent e0cd8f3 commit 5d95fa0

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <queue>
4+
using namespace std;
5+
6+
// 1. use topology algorithm to check if graph is a DAG.
7+
// 2. construct a convergence start point to link all points which in degree is 0.
8+
// 3. call dijsktra algo to find all short distance from convergence start point.
9+
10+
const int MAXN = 0x3fffffff;
11+
12+
class Node {
13+
public:
14+
int t, s, d;
15+
};
16+
17+
vector<vector<Node>> G;
18+
vector<int> pre;
19+
vector<bool> hasInDegree;
20+
21+
bool isDAG() {
22+
vector<int> inDegree(G.size(), 0);
23+
for (int i = 0; i < G.size(); i++) {
24+
for (int j = 0; j < G[i].size(); j++) {
25+
inDegree[G[i][j].t]++;
26+
}
27+
}
28+
29+
queue<int> q;
30+
for (int i = 0; i < G.size(); i++) {
31+
if (inDegree[i] == 0) q.push(i);
32+
}
33+
34+
int cnt = 0;
35+
while (!q.empty()) {
36+
int u = q.front();
37+
q.pop();
38+
cnt++;
39+
for (int i = 0; i < G[u].size(); i++) {
40+
int v = G[u][i].t;
41+
inDegree[v]--;
42+
if (inDegree[v] == 0) q.push(v);
43+
}
44+
}
45+
46+
return cnt == G.size();
47+
}
48+
49+
void dijkstra() {
50+
int src = G.size() - 1; // G[n] is convergence start point
51+
vector<int> dis(G.size(), MAXN), vou(G.size(), 0);
52+
vector<bool> visited(G.size(), false);
53+
pre.resize(G.size(), -1);
54+
dis[src] = 0;
55+
56+
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
57+
pq.push({0, src});
58+
while (!pq.empty()) {
59+
auto e = pq.top(); pq.pop();
60+
int s = e.first, u = e.second;
61+
visited[u] = true;
62+
63+
if (dis[u] != MAXN && dis[u] < s) continue;
64+
65+
for (int i = 0; i < G[u].size(); i++) {
66+
Node v = G[u][i];
67+
if (visited[v.t]) continue;
68+
if (dis[u] + v.s < dis[v.t]) {
69+
dis[v.t] = dis[u] + v.s;
70+
vou[v.t] = vou[u] + v.d;
71+
pre[v.t] = u;
72+
pq.push({dis[v.t], v.t});
73+
} else if (dis[u] + v.s == dis[v.t] && vou[u] + v.d > vou[v.t]) {
74+
vou[v.t] = vou[u] + v.d;
75+
pre[v.t] = u;
76+
pq.push({dis[v.t], v.t});
77+
}
78+
}
79+
}
80+
}
81+
82+
void print(int t) {
83+
int src = G.size() - 1; // G[n] is convergence start point
84+
if (t == src) return;
85+
print(pre[t]);
86+
if (hasInDegree[t]) cout << "->";
87+
cout << t;
88+
}
89+
90+
91+
int main() {
92+
ios::sync_with_stdio(false);
93+
int n, m, t;
94+
cin >> n >> m;
95+
G.resize(n, vector<Node>());
96+
hasInDegree.resize(n+1, false);
97+
for (int i = 0; i < m; i++) {
98+
Node node = Node();
99+
cin >> t >> node.t >> node.s >> node.d;
100+
hasInDegree[node.t] = true;
101+
G[t].push_back(node);
102+
}
103+
104+
vector<int> starts;
105+
for (int i = 0; i < n; i++) {
106+
if (!hasInDegree[i]) starts.push_back(i);
107+
}
108+
109+
bool isValid = isDAG();
110+
cout << (isValid ? "Okay." : "Impossible.") << endl;
111+
112+
// add a convergence point G[n] to link all starts
113+
G.push_back(vector<Node>());
114+
for (const int &t : starts) {
115+
Node node = Node();
116+
node.t = t;
117+
node.s = node.d = 0;
118+
G[n].push_back(node);
119+
}
120+
dijkstra();
121+
122+
int k;
123+
cin >> k;
124+
for (int i = 0; i < k; i++) {
125+
cin >> t;
126+
if (!hasInDegree[t]) cout << "You may take test " << t << " directly." << endl;
127+
else if (!isValid) cout << "Error." << endl;
128+
else { print(t); cout << endl;}
129+
}
130+
131+
return 0;
132+
}

0 commit comments

Comments
 (0)