您的位置:首页 > 其它

BZOJ 1497: [NOI2006]最大获利

2017-07-02 22:29 381 查看
学习了一发最大权闭合图

这题裸的,直接套用最大权闭合图的建图方法

#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
#define INF 2e9
#define maxn 310050
#define M 60000
using namespace std;

int read()
{
int a=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){a=a*10+c-'0';c=getchar();}
return a*f;
}

struct edge{int next,to,f;}e[maxn];
int n,m,cnt,S,T;
int head[M],d[M],cur[M];

void add(int x,int y,int v)
{
e[++cnt].next=head[x];
e[cnt].to=y,e[cnt].f=v;
head[x]=cnt;
e[++cnt].next=head[y];
e[cnt].to=x,e[cnt].f=0;
head[y]=cnt;
}

bool bfs()
{
memset(d,-1,sizeof(d));
queue<int>Q;
Q.push(S),d[S]=0;
while(!Q.empty())
{
int x=Q.front();Q.pop();
if(x==T) return 1;
for(int i=head[x];i;i=e[i].next)
if(d[e[i].to]==-1&&e[i].f)
{
Q.push(e[i].to);
d[e[i].to]=d[x]+1;
}
}
return 0;
}

int dfs(int x,int a)
{
if(x==T) return a;
int f,flow=0;
for(int &i=cur[x];i;i=e[i].next)
if(e[i].f&&d[e[i].to]==d[x]+1)
{
f=dfs(e[i].to,min(a,e[i].f));
e[i].f-=f;
e[i^1].f+=f;
flow+=f;
a-=f;
if(!a) break;
}
if(!flow) d[x]=-1;
return flow;
}

int dinic()
{
int maxflow=0;
while(bfs())
{
for(int i=0;i<=T;++i) cur[i]=head[i];
maxflow+=dfs(S,INF);
}
return maxflow;
}

int main(void)
{
n=read(),m=read();
cnt=1,S=0,T=n+m+1;
int x,y,z;
for(int i=1;i<=n;++i)
{
x=read();
add(m+i,T,x);
}
int sum=0;
for(int i=1;i<=m;++i)
{
x=read(),y=read(),z=read();
add(S,i,z);
add(i,m+x,INF);
add(i,m+y,INF);
sum+=z;
}
printf("%d",sum-dinic());
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: