hdu4917 A simple brute force problem.(最大权闭合)

来源:互联网 发布:用户手册 软件功能 编辑:程序博客网 时间:2024/05/22 09:19

n个项目,m个技术,每个项目可以赚取x[i]元,每个技术需要花费y[i]元,完成每个项目有一定的技术要求,也就是说某些技术必须先完成才能去完成这个项目,而且技术相互之间也有要求的,某些技术必须先完成才能去完成其他的技术。

显然的一点是可以看出来是最大权闭合问题,但是文中说的i必须先去j完成该怎么见图呢,开始我也建错了,样例都过不了,后来才仔细画了个图。

n=1,m=2;

x[1] = 10,y[1] = 4,y[2] = 5;

项目1需要技术1先完成,技术2也需要技术1完成。

主要是技术之间怎么建边。这里建成两种图(技术1->技术2 or 技术2->技术1),算下就知道了。

/*****************************************Author      :Crazy_AC(JamesQi)Time        :2016File Name   :*****************************************/// #pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <algorithm>#include <iomanip>#include <sstream>#include <string>#include <stack>#include <queue>#include <deque>#include <vector>#include <map>#include <set>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <climits>using namespace std;#define MEM(x,y) memset(x, y,sizeof x)#define pk push_backtypedef long long LL;typedef unsigned long long ULL;typedef pair<int,int> ii;typedef pair<ii,int> iii;const double eps = 1e-10;const int inf = 1 << 30;const int INF = 0x3f3f3f3f;const int MOD = 1e9 + 7;const int maxn = 1010;struct Edge{    int from, to, cap, flow;    Edge(){}    Edge(int from,int to,int cap,int flow):from(from),to(to),cap(cap),flow(flow){}};struct ISAP{    int p[maxn], num[maxn], cur[maxn], d[maxn];    int s, t, n, m;    bool vis[maxn];    vector<int> G[maxn];    vector<Edge> edges;    void init(int n) {        this->n = n;        for (int i = 0;i <= n;++i) {            G[i].clear();            d[i] = INF;        }        edges.clear();    }    void addedge(int from,int to,int cap) {        edges.push_back(Edge(from, to, cap, 0));        edges.push_back(Edge(to, from, 0, 0));        m = (int)edges.size();        G[from].push_back(m - 2);        G[to].push_back(m - 1);    }    bool bfs() {        memset(vis, false,sizeof vis);        queue<int> que;        d[t] = 0;        vis[t] = true;        que.push(t);        while(!que.empty()) {            int u = que.front();            que.pop();            for (int i = 0;i < G[u].size();++i) {                Edge& e = edges[G[u][i]^1];                if (e.cap > e.flow && !vis[e.from]) {                    vis[e.from] = true;                    d[e.from] = d[u] + 1;                    que.push(e.from);                }            }        }        return vis[s];    }    int Augment() {        int u = t, flow = INF;        while(u != s) {            Edge& e = edges[p[u]];            flow = min(flow, e.cap - e.flow);            u = edges[p[u]].from;        }        u = t;        while(u != s) {            edges[p[u]].flow += flow;            edges[p[u]^1].flow -= flow;            u = edges[p[u]].from;        }        return flow;    }    int MaxFlow(int s,int t) {        this->s = s,this->t = t;        int ret = 0;        bfs();        if (d[s] >= n) return 0;        memset(num, 0,sizeof num);        memset(cur, 0,sizeof cur);        for (int i = 0;i < n;++i) {            if (d[i] < INF) num[d[i]]++;        }        int u = s;        while(d[s] < n) {            if (u == t) {                ret += Augment();                u = s;            }            bool ok = false;            for (int i = cur[u];i < G[u].size();++i) {                Edge& e = edges[G[u][i]];                if (e.cap > e.flow && d[u] == d[e.to] + 1) {                    ok = true;                    p[e.to] = G[u][i];                    cur[u] = i;                    u = e.to;                    break;                }            }            if (!ok) {                int Min = n - 1;                for (int i = 0;i < G[u].size();++i) {                    Edge& e = edges[G[u][i]];                    if (e.cap > e.flow) Min = min(Min, d[e.to]);                }                if (--num[d[u]] == 0) break;                num[d[u] = Min + 1]++;                cur[u] = 0;                if (u != s) u = edges[p[u]].from;            }        }        return ret;    }}isap;int tmp[51][51];int main(){        // freopen("in.txt","r",stdin);    // freopen("out.txt","w",stdout);    int icase = 0;    int tt;    scanf("%d",&tt);    while(tt--) {        int sum = 0;        int n, m;        scanf("%d%d",&n,&m);        int s = 0, t = n+m+1;        isap.init(t);        int c;        for (int i = 1;i <= n;++i){            scanf("%d",&c);            isap.addedge(s, i, c);            sum += c;        }//cout << "sum = " << sum << endl;        for (int j = 1;j <= m;++j) {            scanf("%d",&c);            isap.addedge(j+n, t, c);        }        int k;        int u, v;        for (int i = 1;i <= n;++i) {            scanf("%d",&k);            while(k--) {                scanf("%d",&u);                isap.addedge(i, u+1+n, INF);            }        }        for (int i = 1;i <= m;++i) {            for (int j = 1;j <= m;++j) {                scanf("%d",&c);                if (c == 1) isap.addedge(i+n,j+n,INF);            }        }        printf("Case #%d: ", ++icase);        printf("%d\n", sum - isap.MaxFlow(s, t));    }    return 0;}



0 0
原创粉丝点击