题意

考虑先将所有价值加上,之后用最小割求最小代价。

考虑每个点对\((i,j)\),我们这样建边:

1.源点向每个点i连\(\sum\limits E_{i,j}\)容量的边。

2.每个点向汇点连雇佣代价容量的边。

3.对每个点对\((i,j)\),从\(i\)向\(j\)连\(2*E_{i,j}\)容量的边。

考虑现在要割掉上图有什么割法:

1.割掉两个连向汇点的边,表示都选上了。

2.割掉两个连向源点的边,表示都不选。

3.割掉一条连向源点的,一条连向汇点的,一条连接两点的,表示一个选一个不选,那么我们要减去\(2*E_{i,j}\),因为不仅之前加多了,这么选后还会再减\(E_{i,j}\)。

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1010;
const int maxm=10010;
const ll inf=1e9;
int n,cnt=1,st,ed;
int head[maxn],cur[maxn],dep[maxn];
ll ans;
ll cost[maxn],sum[maxn];
ll a[maxn][maxn];
struct edge{int to,nxt;ll flow;}e[maxn*maxn<<1];
inline ll read()
{
char c=getchar();ll res=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')res=res*10+c-'0',c=getchar();
return res*f;
}
inline void add(int u,int v,ll w)
{
e[++cnt].nxt=head[u];
head[u]=cnt;
e[cnt].to=v;
e[cnt].flow=w;
}
inline bool bfs()
{
memset(dep,0,sizeof(dep));
for(int i=0;i<=n+1;i++)cur[i]=head[i];
queue<int>q;
q.push(st);dep[st]=1;
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
if(dep[y]||e[i].flow<=0)continue;
dep[y]=dep[x]+1;q.push(y);
}
}
return dep[ed]>0;
}
ll dfs(int x,int goal,ll lim)
{
if(x==goal||lim<=0)return lim;
ll res=lim;
for(int i=cur[x];i;i=e[i].nxt)
{
cur[x]=i;
int y=e[i].to;
if(e[i].flow<=0||dep[y]!=dep[x]+1)continue;
ll tmp=dfs(y,goal,min(res,e[i].flow));
if(tmp<=0)dep[y]=0;
res-=tmp;
e[i].flow-=tmp,e[i^1].flow+=tmp;
if(res<=0)break;
}
return lim-res;
}
inline ll Dinic()
{
ll res=0;
while(bfs())res+=dfs(st,ed,inf);
return res;
}
int main()
{
n=read();
for(int i=1;i<=n;i++)cost[i]=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=read(),ans+=a[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
sum[i]+=a[i][j];
st=0,ed=n+1;
for(int i=1;i<=n;i++)add(st,i,sum[i]),add(i,st,0);
for(int i=1;i<=n;i++)add(i,ed,cost[i]),add(ed,i,0);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j&&a[i][j])add(i,j,2*a[i][j]),add(j,i,0);
printf("%lld",ans-Dinic());
return 0;
}

最新文章

  1. CSS3 莲花盛开动画
  2. shell 命令集
  3. transform你不知道的那些事
  4. 理解Java中的final和static关键字
  5. 阿里云centos配置ftp和svn全过程
  6. Linux kmalloc/kfree 源码解读
  7. linux源码Makefile的详细分析
  8. 使用spool命令从Oracle导出数据
  9. .Net中如何使用MySql连接池
  10. Java泛型介绍!!!
  11. Kivy: Crossplatform Framework for NUI
  12. leetcode第一刷_Merge Sorted Array
  13. Android于JNI调用列出的程序
  14. 201521123059 《Java程序设计》第十周学习总结
  15. 【Python3之正则re】
  16. Nginx websocket反向代理
  17. 各种loading加载中gif图标
  18. JAVA项目中常用的异常处理情况总结
  19. [bug] 验证selenium的显式和隐式等待而发现的一个低级错误
  20. 关于学习oi的一些事项

热门文章

  1. css发展史
  2. DirectShow 常用函数总结
  3. celery生产者-消费者
  4. @PostConstruct - 静态方法调用IOC容器Bean对象
  5. Pycharm 疑难杂症
  6. nginx: [emerg] unknown directive “ ” in /usr/local/nginx/nginx.conf.conf:xx报错处理
  7. 读Xamarin文档记录
  8. Python制作动态二维码只需要一行代码!炒鸡简单!
  9. 进度更新---Responsive Web Design Certification (300 hours)
  10. js监听屏幕方向如何第一次默认不监听