BZOJ 1877 最小费用流
using namespace std;
int n, m;
struct node { int from, to, next, v, c; } e[M];
int ans1, ans2, dis[N], from[N], head[N], q[N << 2], S, T, cnt = 1;
bool inq[N];
void ins(int u, int v, int w, int c) {
cnt++;
e[cnt].from = u; e[cnt].to = v;
e[cnt].v = w; e[cnt].c = c;
e[cnt].next = head[u]; head[u] = cnt;
}
void insert(int u, int v, int w, int c) {
ins(u, v, w, c); ins(v, u, 0, -c);
}
bool spfa() {
for(int i = S; i <= T; i++) dis[i] = inf, inq[i] = false;
queue<int> q;
q.push(S); dis[S] = 0; inq[S] = true;
while(!q.empty()) {
int now = q.front(); q.pop();
inq[now] = false;
int k = head[now];
while(k) {
if (e[k].v && e[k].c + dis[now] < dis[e[k].to]) {
dis[e[k].to] = dis[now] + e[k].c;
from[e[k].to] = k;
if (!inq[e[k].to]) inq[e[k].to] = true, q.push(e[k].to);
}
k = e[k].next;
}
}
return dis[T] != inf;
}
void mcf() {
int x = inf;
int k = from[T];
while(k) {
x = min(x, e[k].v);
k = from[e[k].from];
}
ans1++;
k = from[T];
while(k) {
ans2 += x * e[k].c;
e[k].v -= x;
e[k ^ 1].v += x;
k = from[e[k].from];
}
}
int main() {
scanf("%d%d", &n, &m);
S = 1, T = n + n;
for(int i = 1; i <= m; i++) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
insert(x + n, y, 1, z);
}
for(int i = 2; i < n; i++) insert(i, i + n, 1, 0);
insert(S, S + n, inf, 0);
insert(n, T, inf, 0);
while(spfa()) mcf();
printf("%d %d", ans1, ans2);
return 0;
}
BZOJ3224 splay
#include
#include
#include
using namespace std;
#define N 1000007
int ch[N][2], f[N], size[N], cnt[N], key[N];
int sz, root;
inline void clear(int x) {
ch[x][0] = ch[x][1] = f[x] = size[x] = cnt[x] = key[x] = 0;
}
inline bool get(int x) {
return ch[f[x]][1] == x;
}
inline void update(int x) {
if (x) {
size[x] = cnt[x];
if (ch[x][0]) size[x] += size[ch[x][0]];
if (ch[x][1]) size[x] += size[ch[x][1]];
}
}
inline void rotate(int x) {
int old = f[x], oldf = f[old], whichx = get(x);
ch[old][whichx] = ch[x][whichx^1]; f[ch[old][whichx]] = old;
ch[x][whichx^1] = old; f[old] = x;
f[x] = oldf;
if (f[x]) ch[oldf][ch[oldf][1] == old] = x;
update(old); update(x);
}
inline void splay(int x) {
for(int fa; (fa = f[x]); rotate(x))
if (f[fa]) rotate((get(x) == get(fa)) ? fa : x);
root = x;
}
inline void insert(int x) {
if (root == 0) {
sz++; ch[sz][0] = ch[sz][1] = f[sz] = 0;
size[sz] = cnt[sz] = 1;
key[sz] = x; root = sz; return;
}
int now = root, fa = 0;
while(true) {
if (x == key[now]) {
cnt[now]++; update(now); update(fa); splay(now); break;
}
fa = now;
now = ch[now][x > key[now]];
if (now == 0) {
sz++; ch[sz][0] = ch[sz][1] = 0;
f[sz] = fa; key[sz] = x;
size[sz] = cnt[sz] = 1;
ch[fa][key[fa]break;
}
}
}
inline int find(int x) {
int now = root, ans = 0;
while(true) {
if (x < key[now]) now = ch[now][0];
else {
ans += (ch[now][0]?size[ch[now][0]]:0);
if (x == key[now]) { splay(now); return ans + 1; }
ans += cnt[now];
now = ch[now][1];
}
}
}
inline int findx(int x) {
int now = root;
while(true) {
if (ch[now][0] && x <= size[ch[now][0]]) now = ch[now][0];
else {
int temp = cnt[now] + (ch[now][0]?size[ch[now][0]]:0);
if (x <= temp) return key[now];
x -= temp; now = ch[now][1];
}
}
}
inline int pre() {
int now = ch[root][0];
while(ch[now][1]) now = ch[now][1];
return now;
}
inline int nxt() {
int now = ch[root][1];
while(ch[now][0]) now = ch[now][0];
return now;
}
inline void del(int x) {
int whatever = find(x);
if (cnt[root] > 1) {
cnt[root]--; update(root); return;
}
if (!ch[root][0] && !ch[root][1]) { clear(root); root = 0; return; }
if (!ch[root][0]) {
int oldroot = root; root = ch[root][1]; f[root] = 0;
clear(oldroot); return;
}
if (!ch[root][1]) {
int oldroot = root; root = ch[root][0]; f[root] = 0;
clear(oldroot); return ;
}
int leftbig = pre(), oldroot = root;
splay(leftbig);
f[ch[oldroot][1]] = root;
ch[root][1] = ch[oldroot][1];
clear(oldroot);
update(root); return;
}
int main(){
int n,opt,x;
scanf("%d",&n);
for (int i=1;i<=n;++i){
scanf("%d%d",&opt,&x);
switch(opt){
case 1: insert(x); break;
case 2: del(x); break;
case 3: printf("%d\n",find(x)); break;
case 4: printf("%d\n",findx(x)); break;
case 5: insert(x); printf("%d\n",key[pre()]); del(x); break;
case 6: insert(x); printf("%d\n",key[nxt()]); del(x); break;
}
}
return 0;
}
BZOJ1834 裸最大流+费用流
using namespace std;
int n, m, k;
struct node { int from, to, next, v, c, t; } e[M];
int ans, ans2, dis[N], from[N], head[N], q[N << 2], S, T, cnt = 1;
bool inq[N];
int h[N];
void ins(int u, int v, int w, int c) {
cnt++;
e[cnt].from = u; e[cnt].to = v;
e[cnt].v = w; e[cnt].t = c;
e[cnt].next = head[u]; head[u] = cnt;
}
void insert(int u, int v, int w, int c) {
ins(u, v, w, c); ins(v, u, 0, -c);
}
void ins2(int u, int v, int w, int c) {
cnt++;
e[cnt].from = u; e[cnt].to = v;
e[cnt].v = w; e[cnt].c = c;
e[cnt].next = head[u]; head[u] = cnt;
}
void insert2(int u, int v, int w, int c) {
ins2(u, v, w, c); ins2(v, u, 0, -c);
}
void build() {
int tot = cnt;
for(int i = 2; i <= tot; i+= 2) if (i % 2 == 0)
insert2(e[i].from, e[i].to, inf, e[i].t);
}
bool bfs() {
for(int i = S; i <= T; i++) h[i] = -1;
queue<int> q;
q.push(S); h[S] = 0;
while(!q.empty()) {
int now = q.front(); q.pop();
int k = head[now];
while(k) {
if (e[k].v && h[e[k].to] == -1) h[e[k].to] = h[now] + 1, q.push(e[k].to);
k = e[k].next;
}
}
return h[T] != -1;
}
int dfs(int x, int f) {
if (x == T) return f;
int k = head[x], used = 0;
while(k) {
if (e[k].v && h[e[k].to] == h[x] + 1) {
int w = f - used;
w = dfs(e[k].to, min(w, e[k].v));
e[k].v -= w;
e[k ^ 1].v += w;
used += w;
if (used == f) return f;
}
k = e[k].next;
}
if (!used) h[x] = -1;
return used;
}
void dinic() {
while(bfs()) ans += dfs(S, inf);
}
bool spfa() {
for(int i = S; i <= T; i++) dis[i] = inf, inq[i] = false;
queue<int> q;
q.push(S); dis[S] = 0; inq[S] = true;
while(!q.empty()) {
int now = q.front(); q.pop();
inq[now] = false;
int k = head[now];
while(k) {
if (e[k].v && e[k].c + dis[now] < dis[e[k].to]) {
dis[e[k].to] = dis[now] + e[k].c;
from[e[k].to] = k;
if (!inq[e[k].to]) inq[e[k].to] = true, q.push(e[k].to);
}
k = e[k].next;
}
}
return dis[T] != inf;
}
void mcf() {
int x = inf;
int k = from[T];
while(k) {
x = min(x, e[k].v);
k = from[e[k].from];
}
k = from[T];
while(k) {
ans2 += x * e[k].c;
e[k].v -= x;
e[k ^ 1].v += x;
k = from[e[k].from];
}
}
int main() {
scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= m; i++) {
int x, y, z, t;
scanf("%d%d%d%d", &x, &y, &z, &t);
insert(x, y, z, t);
}
S = 1, T = n;
dinic();
build();
insert2(0, 1, k, 0);
S = 0;
T = n;
while(spfa()) mcf();
printf("%d %d", ans, ans2);
return 0;
}