📄 algorithms in c, third edition,part 5,code.txt
字号:
double GRAPHspDIST(Graph G, int s, int t);
int GRAPHspPATH(Graph G, int s, int t);
-----
void GRAPHdiameter(Graph G)
{ int v, w, vMAX = 0, wMAX = 0;
double MAX = 0.0;
GRAPHspALL(G);
for (v = 0; v < G->V; v++)
for (w = 0; w < G->V; w++)
if (GRAPHspPATH(G, v, w) != G->V)
if (MAX < GRAPHspDIST(G, v, w))
{ vMAX = v; wMAX = w;
MAX = GRAPHspDIST(G, v, w); }
printf("Diameter is %f\n", MAX);
for (v = vMAX; v != wMAX; v = w)
{ printf("%d-", v);
w = GRAPHspPATH(G, v, wMAX); }
printf("%d\n", w);
}
-----
static int st[maxV];
static double wt[maxV];
void GRAPHspALL(Graph G)
{ int v, w; Graph R = GRAPHreverse(G);
G->dist = MATRIXdouble(G->V, G->V, maxWT);
G->path = MATRIXint(G->V, G->V, G->V);
for (v = 0; v < G->V; v++)
{
GRAPHpfs(R, v, st, wt);
for (w = 0; w < G->V; w++)
G->dist[w][v] = wt[w];
for (w = 0; w < G->V; w++)
if (st[w] != -1) G->path[w][v] = st[w];
}
}
double GRAPHspDIST(Graph G, int s, int t)
{ return G->dist[s][t]; }
int GRAPHspPATH(Graph G, int s, int t)
{ return G->path[s][t]; }
-----
void GRAPHspALL(Graph G)
{ int i, s, t;
double **d = MATRIXdouble(G->V, G->V, maxWT);
int **p = MATRIXint(G->V, G->V, G->V);
for (s = 0; s < G->V; s++)
for (t = 0; t < G->V; t++)
if ((d[s][t] = G->adj[s][t]) < maxWT)
p[s][t] = t;
for (i = 0; i < G->V; i++)
for (s = 0; s < G->V; s++)
if (d[s][i] < maxWT)
for (t = 0; t < G->V; t++)
if (d[s][t] > d[s][i]+d[i][t])
{ p[s][t] = p[s][i];
d[s][t] = d[s][i]+d[i][t]; }
G->dist = d; G->path = p;
}
-----
static int ts[maxV];
void GRAPHlpt(Graph G, int s, int st[], double wt[])
{ int i, v, w; link t;
GRAPHts(G, ts);
for (v = ts[i = 0]; i < G->V; v = ts[i++])
for (t = G->adj[v]; t != NULL; t = t->next)
if (wt[w = t->v] < wt[v] + t->wt)
{ st[w] = v; wt[w] = wt[v] + t->wt; }
}
-----
void SPdfsR(Graph G, int s)
{ link u; int i, t; double wt;
int **p = G->path; double **d = G->dist;
for (u = G->adj[s]; u != NULL; u = u->next)
{
t = u->v; wt = u->wt;
if (d[s][t] > wt)
{ d[s][t] = wt; p[s][t] = t; }
if (d[t][t] == maxWT) SPdfsR(G, t);
for (i = 0; i < G->V; i++)
if (d[t][i] < maxWT)
if (d[s][i] > wt+d[t][i])
{ d[s][i] = wt+d[t][i]; p[s][i] = t; }
}
}
void GRAPHspALL(Graph G)
{ int v;
G->dist = MATRIXdouble(G->V, G->V, maxWT);
G->path = MATRIXint(G->V, G->V, G->V);
for (v = 0; v < G->V; v++)
if (G->dist[v][v] == maxWT) SPdfsR(G, v);
}
-----
#include <stdio.h>
#include "GRAPH.h"
#define Nmax 1000
main(int argc, char *argv[])
{ int i, s, t, N = atoi(argv[1]);
double length[Nmax], start[Nmax];
int st[Nmax];
Graph G = GRAPHinit(N);
for (i = 0; i < N; i++)
scanf("%lf", &length[i]);
while (scanf("%d %d", &s, &t) != EOF)
GRAPHinsertE(G, EDGE(s, t, length[s]));
GRAPHlpt(G, 0, st, start);
for (i = 0; i < N; i++)
printf("%3d %6.2f\n", i, start[i]);
}
-----
void GRAPHbf(Graph G, int s, int st[], double wt[])
{ int v, w; link t; int N = 0;
QUEUEinit(G->E);
for (v = 0; v < G->V; v++)
{ st[v] = -1; wt[v] = maxWT; }
wt[s] = 0.0; st[s] = 0;
QUEUEput(s); QUEUEput(G->V);
while (!QUEUEempty())
if ((v = QUEUEget()) == G->V)
{ if (N++ > G->V) return; QUEUEput(G->V); }
else
for (t = G->adj[v]; t != NULL; t = t->next)
if (wt[w = t->v] > wt[v] + t->wt)
{ wt[w] = wt[v] + t->wt;
QUEUEput(w); st[w] = v; }
}
----------
CHAPTER 22. Network Flow
-----
#include <stdlib.h>
#include "GRAPH.h"
typedef struct node *link;
struct node
{ int v; int cap; int flow; link dup; link next;};
struct graph
{ int V; int E; link *adj; };
link NEW(int v, int cap, int flow, link next)
{ link x = malloc(sizeof *x);
x->v = v; x->cap = cap; x->flow = flow;
x->next = next;
return x;
}
Graph GRAPHinit(int V)
{ int i;
Graph G = malloc(sizeof *G);
G->adj = malloc(V*sizeof(link));
G->V = V; G->E = 0;
for (i = 0; i < V; i++) G->adj[i] = NULL;
return G;
}
void GRAPHinsertE(Graph G, Edge e)
{ int v = e.v, w = e.w;
G->adj[v] = NEW(w, e.cap, e.flow, G->adj[v]);
G->adj[w] = NEW(v, -e.cap, -e.flow, G->adj[w]);
G->adj[v]->dup = G->adj[w];
G->adj[w]->dup = G->adj[v];
G->E++;
}
-----
static int flowV(Graph G, int v)
{ link t; int x = 0;
for (t = G->adj[v]; t != NULL; t = t->next)
x += t->flow;
return x;
}
int GRAPHflow(Graph G, int s, int t)
{ int v, val = flowV(G, s);
for (v = 0; v < G->V; v++)
if ((v != s) && (v != t))
if (flowV(G, v) != 0) return 0;
if (val + flowV(G, t) != 0) return 0;
if (val <= 0) return 0;
return val;
}
-----
static int wt[maxV];
#define Q (u->cap < 0 ? -u->flow : u->cap - u->flow)
int GRAPHpfs(Graph G, int s, int t, link st[])
{ int v, w, d = M; link u;
PQinit(); priority = wt;
for (v = 0; v < G->V; v++)
{ st[v] = NULL; wt[v] = 0; PQinsert(v); }
wt[s] = M; PQinc(s);
while (!PQempty())
{
v = PQdelmax();
if ((wt[v] == 0) || (v == t)) break;
for (u = G->adj[v]; u != NULL; u = u->next)
if (Q > 0)
if (P > wt[w = u->v])
{ wt[w] = P; PQinc(w); st[w] = u; }
wt[v] = M;
}
if (wt[t] == 0) return 0;
for (w = t; w != s; w = st[w]->dup->v)
{ u = st[w]; d = ( Q > d ? d : Q ); }
return d;
}
void GRAPHmaxflow(Graph G, int s, int t)
{ int x, d;
link st[maxV];
while ((d = GRAPHpfs(G, s, t, st)) != 0)
for (x = t; x != s; x = st[x]->dup->v)
{ st[x]->flow += d; st[x]->dup->flow -= d; }
}
-----
static int h[maxV], wt[maxV];
#define P ( Q > wt[v] ? wt[v] : Q )
#define Q (u->cap < 0 ? -u->flow : u->cap - u->flow)
int GRAPHmaxflow(Graph G, int s, int t)
{ int v, w, x; link u;
GRAPHdist(G, t, h);
GQinit();
for (v = 0; v < G->V; v++) wt[v] = 0;
GQput(s); wt[s] = maxWT; wt[t] = -maxWT;
while (!GQempty())
{
v = GQget();
for (u = G->adj[v]; u != NULL; u = u->next)
if (P > 0 && v == s || h[v] == h[u->v]+1)
{
w = u->v; x = P;
u->flow += x; u->dup->flow -= x;
wt[v] -= x; wt[w] += x;
if ((w != s) && (w != t)) GQput(w);
}
if ((v != s) && (v != t))
if (wt[v] > 0) { h[v]++; GQput(v); }
}
}
-----
void insertSTlinks(Graph G, int s, int t)
{ int i, sd;
for (i = 0; i < G->V; i++)
if ((sd = G->sd[i]) >= 0)
GRAPHinsertE(G, EDGE(s, i, sd, 0, 0));
for (i = 0; i < G->V; i++)
if ((sd = G->sd[i]) < 0)
GRAPHinsertE(G, EDGE(i, t, -sd, 0, 0));
}
void removeSTlinks(Graph G)
{ int i;
for (i = 0; i < G->V; i++)
G->adj[i] = G->adj[i]->next;
}
int GRAPHfeasible(Graph G)
{ int s = G->V, t = G->V+1, sd = 0; link u;
insertSTlinks(G, s, t); G->V += 2;
GRAPHmaxflow(G, s, t);
for (u = G->adj[s]; u != NULL; u = u->next)
sd += u->cap - u->flow;
for (u = G->adj[t]; u != NULL; u = u->next)
sd += u->cap - u->flow;
G->V -= 2; removeSTlinks(G);
return sd;
}
-----
#include <stdio.h>
#include "GRAPH.h"
main(int argc, char *argv[])
{ Graph G; int i, v, w, E, V = atoi(argv[1]);
G = GRAPHinit(2*V+2);
for (i = 1; i <= V; i++)
GRAPHinsertE(G, EDGE(0, i, 1, 0));
while (scanf("%d %d", &v, &w) != EOF)
GRAPHinsertE(G, EDGE(v, w, 1, 0));
for (i = V+1; i <= V+V; i++)
GRAPHinsertE(G, EDGE(i, V+V+1, 1, 0));
if (GRAPHmaxflow(G, 0, V+V+1) == 0) return;
E = GRAPHedges(a, G);
for (i = 0; i < E; i++)
if ((a[i].v != 0) && (a[i].w != V+V+1))
if (a[i].flow == 1)
printf("%d-%d\n", a[i].v, a[i].w);
}
-----
int GRAPHcost(Graph G)
{ int i; link u; int cost = 0;
for (i = 0; i < G->V; i++)
for (u = G->adj[i]; u != NULL; u = u->next)
if ((u->cap > 0) && (u->cost != C))
cost += (u->flow)*(u->cost);
return cost;
}
-----
void addflow(link u, int d)
{ u->flow += d; u->dup->flow -=d; }
int GRAPHmincost(Graph G, int s, int t)
{ int d, x, w; link u, st[maxV];
GRAPHmaxflow(G, s, t);
while ((x = GRAPHnegcycle(G, st)) != -1)
{
u = st[x]; d = Q;
for (w = u->dup->v; w != x; w = u->dup->v)
{ u = st[w]; d = ( Q > d ? d : Q ); }
u = st[x]; addflow(u, d);
for (w = u->dup->v; w != x; w = u->dup->v)
{ u = st[w]; addflow(u, d); }
}
return GRAPHcost(G);
}
-----
#define ST(i) st[i]->dup->v
static int valid, phi[maxV];
int phiR(link st[], int v)
{
if (ST(v) == v)
{ mark[v] = valid; return -C; }
if (mark[v] != valid)
phi[v] =phiR(st, ST(v)) - st[v]->cost;
mark[v] = valid;
return phi[v];
}
-----
int lca(link st[], int u, int v)
{ int i, j;
mark[u] = ++valid; mark[v] = valid;
while (u != v)
{
u = ST(u); v = ST(v);
if (u != ST(u) && mark[u] == valid) return u;
mark[u] = valid;
if (v != ST(v) && mark[v] == valid) return v;
mark[v] = valid;
}
return u;
}
link augment(link st[], link x)
{ link u, cyc[maxV]; int d, N;
int t, i = x->v, j = x->dup->v;
t = lca(st, i, j);
cyc[0] = x; N = 1;
while (i != t)
{ cyc[N++] = st[i]->dup; i = ST(i); }
while (j != t)
{ cyc[N++] = st[j]; j = ST(j); }
for (i = 0, d = C; i < N; i++)
{ u = cyc[i]; d = Q > d ? d : Q; }
for (i = 0; i < N; i++) addflow(cyc[i], d);
for (i = 0; i < N-1; i++)
{ u = cyc[N-1-i]; if (Q == 0) return u; }
}
-----
int onpath(link st[], int a, int b, int c)
{ int i;
for (i = a; i != c; i = ST(i))
if (i == b) return 1;
return 0;
}
int reverse(link st[], int u, int x)
{ int i;
while (i != st[x]->v)
{ i = st[u]->v; st[i] = st[u]->dup; u = i; }
}
int update(link st[], link w, link y)
{ int t, u = y->v, v = y->dup->v, x = w->v;
if (st[x] != w->dup) x = w->dup->v;
t = lca(st, u, v);
if (onpath(st, u, x, t))
{ st[u] = y; reverse(st, u, x); return; }
if (onpath(st, v, x, t))
{ st[v] = y->dup; reverse(st, v, x); return; }
}
-----
#define R(u) u->cost - phi[u->dup->v] + phi[u->v]
void addflow(link u, int d)
{ u->flow += d; u->dup->flow -=d; }
int GRAPHmincost(Graph G, int s, int t)
{ int v; link u, x, st[maxV];
GRAPHinsertE(G, EDGE(s, t, M, M, C));
initialize(G, s, t, st);
for (valid = 1; valid++; )
{
for (v = 0; v < G->V; v++)
phi[v] = phiR(st, v);
for (v = 0, x = G->adj[v]; v < G->V; v++)
for (u = G->adj[v]; u != NULL; u = u->next)
if (Q > 0)
if (R(u) < R(x)) x = u;
if (R(x) == 0) break;
update(st, augment(st, x), x);
}
return GRAPHcost(G);
}
-----
int R(link st[], link u)
{ return u->cost
- phiR(st, u->dup->v) + phiR(st, u->v); }
int GRAPHmincost(Graph G, int s, int t)
{ int v, old = 0; link u, x, st[maxV];
GRAPHinsertE(G, EDGE(s, t, M, M, C));
initialize(G, s, t, st);
for (valid = 1; valid != old; old = valid)
for (v = 0; v < G->V; v++)
for (u = G->adj[v]; u != NULL; u = u->next)
if ((Q > 0) && (R(st, u) < 0))
{ update(st, augment(st, u), u); valid++; }
return GRAPHcost(G);
}
-----
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -