比赛 20160415 评测结果 AAAAAAAAAA
题目名称 能量网络 最终得分 100
用户昵称 _Horizon 运行时间 0.722 s
代码语言 C++ 内存使用 7.09 MiB
提交时间 2016-04-15 11:05:49
显示代码纯文本
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define maxn 55010
using namespace std;
const int inf = 0x7fffffff;
queue<int>Q;

int d[maxn], m, n;

vector<int> G[1010];

struct Edge{
    int to, next, w;
    Edge(int v = 0, int nxt = 0, int w = 0){
        to = v, next = nxt, this->w = w;
    }
}edge[maxn * 10];

int h[maxn], cur[maxn], cnt = 1, S, T;

void add(int u, int v, int w){
    edge[++ cnt] = Edge(v, h[u], w); h[u] = cnt;
    edge[++ cnt] = Edge(u, h[v], 0); h[v] = cnt;
}

bool BFS(){
    memset(d, -1, sizeof d);
    Q.push(S); d[S] = 0;
    while(!Q.empty()){
        int u = Q.front(); Q.pop();
        for(int i = h[u]; i; i = edge[i].next){
            if(edge[i].w == 0)continue;
            int v = edge[i].to;
            if(d[v] == -1)d[v] = d[u] + 1, Q.push(v);
        }
    }return d[T] != -1;
}

int DFS(int x, int a){
    if(x == T || a == 0)
        return a;
    int used = 0, f;
    for(int i = h[x]; i; i = edge[i].next){
        int v = edge[i].to;
        if(d[v] == d[x] + 1 && edge[i].w){
            f = DFS(v, min(a-used, edge[i].w));
            edge[i].w -= f;
            edge[i^1].w += f;
            used += f;
            if(used == a)return used;
        }
    }
    if(!used)d[x] = -1;
    return used;
}

int Dinic(){
    int ret = 0;
    while(BFS())
        ret += DFS(S, inf);
    return ret;
}

int a[maxn], b[maxn], A[maxn];

bool cmp(const int& i, const int& j){
    return a[i] > a[j];
}

int main(){
    freopen("energynet.in", "r", stdin);
    freopen("energynet.out", "w", stdout);
    scanf("%d%d", &n, &m);
    S = 0, T = 55000;
    for(int i = 1; i <= n; i ++)
        scanf("%d", &a[i]);
    for(int i = 1; i <= n; i ++)
        scanf("%d", &b[i]);
    int u, v;
    for(int i = 1; i <= m; i ++){
        scanf("%d%d", &u, &v);
        A[u] = max(A[u], a[v]);
        G[u].push_back(v);
    }
    int c = n;
    for(int i = 1; i <= n; i ++){
        sort(G[i].begin(), G[i].end(), cmp);
        add(S, i, b[i]);
        for(int j = 0; j < G[i].size(); j ++){
            int now = G[i][j];
            ++ c;
            add(now, c, inf);
            if(j != (int)G[i].size() - 1)
                add(c, T, a[now] - a[G[i][j+1]]);
            else add(c, T, a[now]);
            if(j)add(c-1, c, inf);
        }
    }
    printf("%d\n", Dinic());
    return 0;
}