Skip to content

Commit

Permalink
WF2019
Browse files Browse the repository at this point in the history
  • Loading branch information
Luffbee committed Mar 16, 2019
2 parents a3e8525 + 1663e1e commit a4162cd
Show file tree
Hide file tree
Showing 14 changed files with 701 additions and 128 deletions.
129 changes: 129 additions & 0 deletions DFAMinimization.cpp
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.
173 changes: 173 additions & 0 deletions graph/Kpath.cpp
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";
}
}


Loading

0 comments on commit a4162cd

Please sign in to comment.