隐藏页面特效

3698: XWW的难题[有源汇上下界最大流]

3698: XWW的难题

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 354  Solved: 178
[Submit][Status][Discuss]

Description

XWW是个影响力很大的人,他有很多的追随者。这些追随者都想要加入XWW教成为XWW的教徒。但是这并不容易,需要通过XWW的考核。
XWW给你出了这么一个难题:XWW给你一个N*N的正实数矩阵A,满足XWW性。
称一个N*N的矩阵满足XWW性当且仅当:(1)A[N][N]=0;(2)矩阵中每行的最后一个元素等于该行前N-1个数的和;(3)矩阵中每列的最后一个元素等于该列前N-1个数的和。
现在你要给A中的数进行取整操作(可以是上取整或者下取整),使得最后的A矩阵仍然满足XWW性。同时XWW还要求A中的元素之和尽量大。

Input

第一行一个整数N,N ≤ 100。
接下来N行每行包含N个绝对值小于等于1000的实数,最多一位小数。

Output

输出一行,即取整后A矩阵的元素之和的最大值。无解输出No。

Sample Input

4
3.1 6.8 7.3 17.2
9.6 2.4 0.7 12.7
3.6 1.2 6.5 11.3
16.3 10.4 14.5 0

Sample Output

129

HINT

 

【数据规模与约定】

有10组数据,n的大小分别为10,20,30...100。

【样例说明】

样例中取整后满足XWW性的和最大的矩阵为:

3 7 8 18

10 3 0 13

4 1 7 12

17 11 15 0


 

 

Source

 
[Submit][Status]

 

#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int N=205; const int M=1e5+5; struct edge{int v,next,cap;}e[M];int tot=1,head[N]; int n,S,T,SS,TT,res,sum,in[N],dis[N],q[M]; double a[N][N]; inline void add(int x,int y,int z){ e[++tot].v=y;e[tot].cap=z;e[tot].next=head[x];head[x]=tot; e[++tot].v=x;e[tot].cap=0;e[tot].next=head[y];head[y]=tot; } bool bfs(int S,int T){ memset(dis,-1,sizeof dis); int h=0,t=1;q[t]=S;dis[S]=0; while(h!=t){ int x=q[++h]; for(int i=head[x];i;i=e[i].next){ if(e[i].cap&&dis[e[i].v]==-1){ dis[e[i].v]=dis[x]+1; if(e[i].v==T) return 1; q[++t]=e[i].v; } } } return 0; } int dfs(int x,int T,int f){ if(x==T) return f; int used=0,t; for(int i=head[x];i;i=e[i].next){ if(e[i].cap&&dis[e[i].v]==dis[x]+1){ t=dfs(e[i].v,T,min(e[i].cap,f)); e[i].cap-=t;e[i^1].cap+=t; used+=t;f-=t; if(!f) return used; } } if(!used) dis[x]=-1; return used; } void dinic(int S,int T){ res=0; while(bfs(S,T)) res+=dfs(S,T,2e9); } void mapping(){ scanf("%d",&n); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ scanf("%lf",&a[i][j]); } } S=n<<1|1;T=S+1;SS=S+2;TT=S+3; for(int i=1;i<n;i++){ if(a[i][n]!=(int)a[i][n]) add(S,i,1); in[S]-=(int)a[i][n];in[i]+=(int)a[i][n]; } for(int i=1;i<n;i++){ if(a[n][i]!=(int)a[n][i]) add(i+n,T,1); in[i+n]-=(int)a[n][i];in[T]+=(int)a[n][i]; } for(int i=1;i<n;i++){ for(int j=1;j<n;j++){ if(a[i][j]!=(int)a[i][j]) add(i,j+n,1); in[i]-=(int)a[i][j];in[j+n]+=(int)a[i][j]; } } for(int i=1;i<=TT;i++){ if(in[i]>0) add(SS,i,in[i]),sum+=in[i]; if(in[i]<0) add(i,TT,-in[i]); } add(T,S,2e9); } int main(){ mapping(); dinic(SS,TT); if(res!=sum){puts("No");return 0;} dinic(S,T); printf("%d\n",res*3); return 0; }

 


__EOF__

本文作者shenben
本文链接https://www.cnblogs.com/shenben/p/6625997.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   神犇(shenben)  阅读(272)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示