您的位置:首页 > 其它

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

2016-03-01 23:27 387 查看
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        :2016
File 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_back
typedef 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: