-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
701 additions
and
128 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
#include <bits/stdc++.h> | ||
|
||
using namespace std; | ||
|
||
const int N = 1e5+10; | ||
const int B = 16; | ||
struct DFA { | ||
int n, b, cnt, start; | ||
int go[N][B], cls[N], pos[N]; | ||
int stat[N], bnd[N][3]; | ||
bool acc[N], vis[N], inq[N]; | ||
vector<int> from[N][B]; | ||
|
||
inline void init(int nn, int bb, int s) { | ||
n = nn, b = bb, start = s; | ||
memset(vis, 0, sizeof(bool) * n); | ||
memset(inq, 0, sizeof(bool) * n); | ||
memset(acc, 0, sizeof(bool) * n); | ||
cnt = 0; | ||
} | ||
|
||
inline void add(int x, int t, int y) { | ||
go[x][t] = y; | ||
} | ||
|
||
inline void accept(int x) { | ||
acc[x] = true; | ||
} | ||
|
||
inline int size(int x) { | ||
return bnd[x][1] - bnd[x][0] + 1; | ||
} | ||
|
||
inline void addclass(int l, int r) { | ||
bnd[cnt][0] = bnd[cnt][2] = l; | ||
bnd[cnt][1] = r; | ||
for (int i = l; i <= r; ++i) cls[stat[i]] = cnt; | ||
cnt++; | ||
} | ||
|
||
inline void refine(int c, int p) { | ||
if (p == bnd[c][2]) bnd[c][2]++; | ||
else { | ||
int x = stat[p], y = stat[bnd[c][2]]; | ||
swap(stat[p], stat[bnd[c][2]++]); | ||
swap(pos[x], pos[y]); | ||
} | ||
} | ||
|
||
inline void initMini() { | ||
int l = 0, r = 0, k = 0; | ||
stat[r++] = start; | ||
vis[start] = true; | ||
while (l != r) { | ||
int x = stat[l++]; | ||
if (acc[x]) swap(stat[l-1], stat[k++]); | ||
for (int i = 0; i < b; ++i) { | ||
int y = go[x][i]; | ||
from[y][i].push_back(x); | ||
if (!vis[y]) { | ||
stat[r++] = y; | ||
vis[y] = true; | ||
} | ||
} | ||
} | ||
for (int i = 0; i < r; ++i) pos[stat[i]] = i; | ||
addclass(0, k-1); | ||
addclass(k, r-1); | ||
} | ||
|
||
void minimization() { | ||
initMini(); | ||
queue<int> q; | ||
vector<int> tmp; | ||
q.push(0); | ||
inq[0] = true; | ||
while (!q.empty()) { | ||
int x = q.front(); q.pop(); | ||
int l = bnd[x][0], r = bnd[x][1]; | ||
inq[x] = false; | ||
for (int t = 0; t < b; ++t) { | ||
tmp.clear(); | ||
for (int i = l; i <= r; ++i) { | ||
for (int y : from[stat[i]][t]) { | ||
refine(cls[y], pos[y]); | ||
tmp.push_back(cls[y]); | ||
} | ||
} | ||
for (int c : tmp) { | ||
if (bnd[c][2] == bnd[c][0]) continue; | ||
else if (bnd[c][1] < bnd[c][2]) bnd[c][2] = bnd[c][0]; | ||
else { | ||
addclass(bnd[c][0], bnd[c][2]-1); | ||
bnd[c][0] = bnd[c][2]; | ||
if (inq[c] || size(c) > size(cnt-1)) c = cnt-1; | ||
q.push(c); | ||
inq[c] = true; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
void show() { | ||
cout << cnt << ' ' << cls[0] << '\n'; | ||
for (int i = 0; i < cnt; ++i) { | ||
if (acc[stat[bnd[i][0]]]) cout << "G "; | ||
else cout << "B "; | ||
} cout << '\n'; | ||
for (int i = 0; i < cnt; ++i) { | ||
for (int j = 0; j < b; ++j) { | ||
cout << cls[go[stat[bnd[i][0]]][j]] << ' '; | ||
} cout << '\n'; | ||
} | ||
} | ||
} dfa; | ||
|
||
int main() { | ||
int b, m; cin >> b >> m; | ||
dfa.init(m, b, 0); | ||
for (int i = 0; i < m; ++i) { | ||
for (int j = 0; j < b; ++j) { | ||
dfa.add(i, j, (i * b + j) % m); | ||
} | ||
} | ||
dfa.accept(0); | ||
dfa.minimization(); | ||
dfa.show(); | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
const int N = 1e3+10; | ||
const int M = 1e4+10; | ||
const LL INF = 0x3f3f3f3f3f3f3f3f; | ||
|
||
struct Edge { | ||
LL w; | ||
int v, nxt; | ||
} edge[M], edge2[M]; | ||
int etot; | ||
|
||
int head[N], head2[N]; | ||
|
||
void add(int u, int v, LL l) { | ||
++etot; | ||
edge[etot] = {l, v, head[u]}; | ||
head[u] = etot; | ||
edge2[etot] = {l, u, head2[v]}; | ||
head2[v] = etot; | ||
} | ||
|
||
// M + N * log(M) | ||
struct Node { | ||
pii v; | ||
int nql, ls, rs; | ||
} node[M+15*N] = {{pii(0, 0), -1, 0, 0}}; | ||
int tot; | ||
int newNode() { | ||
++tot; | ||
node[tot] = {{0, 0}, 0, 0, 0}; | ||
return tot; | ||
} | ||
|
||
int meld(int x, int y) { | ||
if (!x) return y; | ||
if (!y) return x; | ||
int ret = newNode(); | ||
if (node[x].v > node[y].v) swap(x, y); | ||
node[ret].v = node[x].v; | ||
int & ls = node[ret].ls = node[x].ls; | ||
int & rs = node[ret].rs = meld(node[x].rs, y); | ||
if (!ls || node[ls].nql < node[rs].nql) swap(ls, rs); | ||
node[ret].nql = node[rs].nql+1; | ||
return ret; | ||
} | ||
|
||
inline int pop(int x) { | ||
return meld(node[x].ls, node[x].rs); | ||
} | ||
|
||
inline pii getMin(int x) { | ||
return node[x].v; | ||
} | ||
|
||
// meld inplace | ||
int meld_in(int x, int y) { | ||
if (!x) return y; | ||
if (!y) return x; | ||
if (node[x].v > node[y].v) swap(x, y); | ||
int & ls = node[x].ls; | ||
int & rs = node[x].rs = meld(node[x].rs, y); | ||
if (!ls || node[ls].nql < node[rs].nql) swap(ls, rs); | ||
node[x].nql = node[rs].nql+1; | ||
return x; | ||
} | ||
|
||
int newHeap(const vector<pii> & vs) { | ||
static int q[2*M]; | ||
int l = 0, r = 0; | ||
q[l] = 0; | ||
for (pii v : vs) { | ||
q[r++] = newNode(); | ||
node[tot].v = v; | ||
} | ||
while (r-l > 1) { | ||
int x = q[l++], y = q[l++]; | ||
q[r++] = meld_in(x, y); | ||
} | ||
return q[l]; | ||
} | ||
|
||
int fa[N]; | ||
LL dis[N]; | ||
bool use[N]; | ||
void dijkstra(int s, int n) { | ||
memset(dis+1, 0x3f, sizeof(LL)*n); | ||
for (int i = 1; i <= n; ++i) use[i] = false; | ||
priority_queue<pii, vector<pii>, greater<pii>> pq; | ||
dis[s] = fa[s] = 0; | ||
pq.push(pii(0, s)); | ||
while (!pq.empty()) { | ||
int u = pq.top().second; | ||
LL d = pq.top().first; | ||
pq.pop(); | ||
if (use[u]) continue; | ||
use[u] = true; | ||
for (int i = head2[u]; i; i = edge2[i].nxt) { | ||
int v = edge2[i].v; | ||
LL dd = d + edge2[i].w; | ||
if (dd < dis[v]) { | ||
dis[v] = dd; | ||
fa[v] = i; | ||
pq.push(pii(dd, v)); | ||
} | ||
} | ||
} | ||
} | ||
|
||
int hp[N]; | ||
bool vis[N]; | ||
vector<pii> tmp; | ||
void dfs(int x, int d) { | ||
tmp.clear(); | ||
vis[x] = true; | ||
for (int i = head[x]; i; i = edge[i].nxt) { | ||
int y = edge[i].v; | ||
if (i != fa[x]) tmp.push_back(pii(edge[i].w+dis[y]-dis[x], i)); | ||
} | ||
hp[x] = newHeap(tmp); | ||
if (!fa[x]) return; | ||
int f = edge[fa[x]].v; | ||
if (!vis[f]) dfs(f, d+1); | ||
hp[x] = meld(hp[x], hp[f]); | ||
} | ||
|
||
LL Kpath(int s, int t, int k, int n) { | ||
priority_queue<pii, vector<pii>, greater<pii>> pq; | ||
dijkstra(t, n); | ||
for (int i = 1; i <= n; ++i) vis[i] = false; | ||
for (int i = 1; i <= n; ++i) if (!vis[i]) dfs(i, 1); | ||
if (dis[s] == INF) return -1; | ||
if (k == 1) return dis[s]; | ||
k--; | ||
LL ans = -1; | ||
if (hp[s]) pq.push({node[hp[s]].v.first, hp[s]}); | ||
while (!pq.empty()) { | ||
pii t = pq.top(); pq.pop(); | ||
LL d = t.first; | ||
if (--k == 0) { | ||
ans = d + dis[s]; | ||
break; | ||
} | ||
int nid = t.second; | ||
int u = edge[node[nid].v.second].v; | ||
int ls = node[nid].ls, rs = node[nid].rs; | ||
if (hp[u]) pq.push({d+node[hp[u]].v.first, hp[u]}); | ||
d -= node[nid].v.first; | ||
if (ls) pq.push({d+node[ls].v.first, ls}); | ||
if (rs) pq.push({d+node[rs].v.first, rs}); | ||
} | ||
return ans; | ||
} | ||
|
||
int main() { | ||
ios::sync_with_stdio(false); cin.tie(0); | ||
tmp.reserve(M); | ||
int n, m; | ||
while (cin >> n >> m) { | ||
tot = etot = 0; | ||
int s, e, k, t; | ||
cin >> s >> e >> k >> t; | ||
memset(head+1, 0, sizeof(int)*n); | ||
memset(head2+1, 0, sizeof(int)*n); | ||
for (int i = 0; i < m; ++i) { | ||
int u, v, w; cin >> u >> v >> w; | ||
add(u, v, w); | ||
} | ||
LL ans = Kpath(s, e, k, n); | ||
if (ans == -1 || ans > t) cout << "Whitesnake!\n"; | ||
else cout << "yareyaredawa\n"; | ||
} | ||
} | ||
|
||
|
Oops, something went wrong.