题目链接:http://poj.org/problem?id=2987
题意简述:一个公司要裁人,给出裁每个人都有个盈利或者损失,如果一个人的上司被裁那么他也将被裁,现在问怎样裁才能使得公司的收益最大,最大为多少?
分析:因为这里上司和下属之间存在一个依赖关系,下属存在的前提或者是必要条件是其上司的存在,所以这满足最大闭权闭合图的性质,用最大权闭合图求解即可
这里注意:结果有可能会超过int,需用__int64或者long long
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const __int64 inf = 0x3fffffffffffff;
const int N = 5050;
const int E = 120050;
int e,head[N];
int num;
int dep[N],que[N],cur[N];
bool vis[N];
struct node
{
int x,y;
int nxt;
__int64 c;
}edge[E];
void addedge(int u,int v,__int64 c)
{
edge[e].x=u;
edge[e].y=v;
edge[e].nxt=head[u];
edge[e].c=c;
head[u]=e++;
edge[e].x=v;
edge[e].y=u;
edge[e].nxt=head[v];
edge[e].c=0;
head[v]=e++;
}
__int64 maxflow(int s,int t)
{
int i,j,k,front,rear,top; __int64 min,res=0;
while(1)
{
memset(dep,-1,sizeof(dep));
front=0;
rear=0;
que[rear++]=s;
dep[s]=0;
while(front!=rear)
{
i=que[front++];
for(j=head[i];j!=-1;j=edge[j].nxt)
if(edge[j].c&&dep[edge[j].y]==-1)
{
dep[edge[j].y]=dep[i]+1;
que[rear++]=edge[j].y;
}
}
if(dep[t]==-1)
break;
memcpy(cur,head,sizeof(head));
for(i=s,top=0;;)
{
if(i==t)
{
min=inf;
for(k=0;k<top;k++)
if(min>edge[que[k]].c)
{
min=edge[que[k]].c;
front=k;
}
for(k=0;k<top;k++)
{
edge[que[k]].c-=min;
edge[que[k]^1].c+=min;
}
res+=min;
i=edge[que[top=front]].x;
}
for(j=cur[i];cur[i]!=-1;j=cur[i]=edge[cur[i]].nxt)
if(dep[edge[j].y]==dep[i]+1&&edge[j].c)
break;
if(cur[i]!=-1)
{
que[top++]=cur[i];
i=edge[cur[i]].y;
}
else
{
if(top==0)
break;
dep[i]=-1;
i=edge[que[--top]].x;
}
}
}
return res;
}
void dfs(int x)
{
vis[x]=1;
num++;
for(int i = head[x];i!=-1;i=edge[i].nxt)
{
int y = edge[i].y;
if(vis[y]==false && edge[i].c)
dfs(y);
}
}
int main ()
{
int n, m;
__int64 sum , c;
int i, x,y;
while(scanf("%d%d",&n,&m)!=EOF)
{
e =0;
memset(head,-1,sizeof(head));
sum = 0;
for(i=1;i<=n;i++)
{
scanf("%I64d",&c);
if(c < 0)
addedge(i,n+1,-c);
else if(c > 0)
{
addedge(0,i,c);
sum+=c;
}
}
for(i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
addedge(x,y,inf);
}
__int64 flow = maxflow(0,n+1);
num=0;
memset(vis,0,sizeof(vis));
dfs(0);
printf("%d %I64d\n",num-1,sum-flow);
}
return 0;
}