题意:
给定n个项目,m个技术难题
下面一行n个数字表示每个项目的收益
下面一行m个数字表示攻克每个技术难题的花费
下面n行第i行表示
第一个数字u表示完成 i 项目需要解决几个技术难题,后面u个数字表示需要解决的问题标号。
下面m*m的矩阵
(i,j) = 1 表示要解决j问题必须先解决i问题。
(若几个问题成环,则需要一起解决)
问:最大收益。
思路:
先给问题缩点一下,每个缩点后的点权就是这个点内所有点权和。
然后跑一个最大权闭合图。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
using namespace std;
const int MAXN = 1000;//点数的最大值
const int MAXM = 40010;//边数的最大值
const int INF = 0x3f3f3f3f;
#define inf 100000000
struct isap{
struct Edge
{
int to,next,cap,flow;
}edge[MAXM];//注意是MAXM
int tol;
int Head[MAXN];
int gap[MAXN],dep[MAXN],cur[MAXN];
void add(int u,int v,int w,int rw = 0)
{
edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = 0;
edge[tol].next = Head[u]; Head[u] = tol++;
edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = 0;
edge[tol].next = Head[v]; Head[v] = tol++;
}
int Q[MAXN];
void BFS(int start,int end)
{
memset(dep,-1,sizeof(dep));
memset(gap,0,sizeof(gap));
gap[0] = 1;
int front = 0, rear = 0;
dep[end] = 0;
Q[rear++] = end;
while(front != rear)
{
int u = Q[front++];
for(int i = Head[u]; i != -1;