费用流模板+splay模板(数组实现)

BZOJ 1877 最小费用流

#include<bits/stdc++.h>
using namespace std;
#define inf 0x7fffffff
#define N 410
#define M 42000
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
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

/**************************************************************
    Problem: 3224
    User: YuHsin
    Language: C++
    Result: Accepted
    Time:672 ms
    Memory:24740 kb
****************************************************************/

#include<iostream>
#include<cstring>
#include<cstdio>
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]<x] = sz;
            update(fa); splay(sz); 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 裸最大流+费用流

#include<bits/stdc++.h>
using namespace std;
#define inf 0x7fffffff
#define N 1210
#define M 32000
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值