大致题意:给你一个竞赛图,告诉你一个记数方法,也即所有边同向的四元组加一,所有相邻两边方向相反的四元组减一。现在让你最大化这个结果。

说实话,不看题解应该很难想到是一个费用流……题解给的也真是简单,个人感觉还可能有错?

我们可以这么考虑,观察它给的计数算法,我们可以发现,他的总的循环次数是。于是我们不妨假设每一次循环都产生贡献,然后减去那些实际上不产生贡献和产生负贡献的东西。考虑什么样的情况下不会产生贡献,我们发现如果一个点,我选择了任意两条它的出边以及对应的点,那么不管第四个点是什么,显然构成的四元组一定不会有正的贡献。而这样的一个四元组在它的计数算法中总共会被计算8次,正着循环4次,反着循环4次。如此一来,不会产生正的贡献的方案数就是:

我们再来考虑重复的情况。根据我的算法,会重复的没有正贡献的四元组,只有形如:a->b<-c->d<-a或a<-b->c<-d->a两种形式。观察这两种形式发现,这两种形式正好是会产生一个负贡献的情况,而重复计算也正好知识重复计算了一次,也就是说这个重复正好帮我们处理的负贡献的情况,可以不管这个重复。

如此,我们就有了大致的方法。对于已经确定的边,我计算每个点的出度,然后带入上式计算答案,不妨设为res。然后我们考虑那些不确定的边。考虑构图,把每一个不确定方向的边(i,j)记录一个编号x,连边<i,x>和<j,x>,分别表示i->j和j->i,流量为1,费用为0。也即每条边要么正向,要么反向。对于点i,如果新增加一条边,那么产生的贡献就是deg[i]*(n-3)*8,即新产生的边与之前每一条搭配一次,对应连边<i',i>,流量为1,费用为deg[i]*(n-3)*8,同时更新度数。最后源点连接每一个i',汇点连接每一个x。构图完毕,跑一边最小费用最大流即可。

关于证明的话,其实可以yy一下。一个点i'->i的次数越多,对应的费用就越高,我们要最大化ans,那么就是要最小化费用,所以要在满足每条边都有确定方向的同时费用最小,对应就是最小费用流了。然后在实际操作中,*(n-3)*8是一个公因子,可以考虑最后再乘以它。设最小费用是cost,则最后的答案就是:

具体操作见代码:

#include<bits/stdc++.h>
#define LL long long
#define mod 998244353
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define INF 0x3f3f3f3f
#define sf(x) scanf("%d",&x)
#define sc(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define clr(x,n) memset(x,0,sizeof(x[0])*(n+5))
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)using namespace std;const int N = 1e3 + 10;struct Edge{int from,to,cap,flow,cost;};
int n,m,s,t,d[N];
int num[N][N],tot;namespace MCMF
{int n,m,s,t,d[N],p[N],a[N];vector<Edge>edges;vector<int>g[N];bool inq[N];void init(int a,int b,int c){n=a; s=b; t=c;edges.clear();for(int i = 0;i<=n;i++)g[i].clear();}void AddEdge(int from,int to,int cap,int cost){edges.push_back(Edge{from,to,cap,0,cost});edges.push_back(Edge{to,from,0,0,-cost});m=edges.size(); g[from].push_back(m-2); g[to].push_back(m-1);}bool BeintmanFord(int &flow,int &cost){for(int i = 0;i<=t;i++)d[i]=INF;memset(inq,0,sizeof(inq));d[s]=0,a[s]=INF,inq[s]=1,p[s]=0;queue<int> q; q.push(s);while(!q.empty()){int u = q.front(); q.pop(); inq[u]=0;for(int i = 0;i<g[u].size();i++){Edge &e = edges[g[u][i]];if(e.cap>e.flow&&d[e.to]>d[u]+e.cost){d[e.to]=d[u]+e.cost; p[e.to]=g[u][i];a[e.to]=min(a[u],e.cap-e.flow);if(!inq[e.to]) {q.push(e.to); inq[e.to]=1;}}}}if(d[t]==INF)return false;flow+=a[t]; cost+=a[t]*d[t];int u = t;while(u!=s){edges[p[u]].flow+=a[t];edges[p[u]^1].flow-=a[t];u=edges[p[u]].from;}return true;}int Min_cost(int &flow,int &cost){flow=0,cost=0;while(BeintmanFord(flow,cost));return cost;}
}char ss[N][N];int main()
{int T; sf(T);while(T--){sf(n); tot=0;clr(d,n);for(int i=0;i<n;i++){scanf("%s",ss[i]);for(int j=0;j<i;j++){if (ss[i][j]=='2'&&ss[j][i]=='2') num[i][j]=2*n+(++tot);if (ss[i][j]=='1') d[i]++;if (ss[i][j]=='0') d[j]++;}}int res=0;for(int i=0;i<n;i++)res+=d[i]*(d[i]-1)/2;int s=2*n+tot+1,t=s+1;MCMF::init(t,s,t);for(int i=0;i<n;i++)for(int j=0;j<i;j++)if (ss[i][j]=='2'){d[i]++; d[j]++;MCMF::AddEdge(i,i+n,1,d[i]-1);MCMF::AddEdge(j,j+n,1,d[j]-1);MCMF::AddEdge(i+n,num[i][j],1,0);MCMF::AddEdge(j+n,num[i][j],1,0);MCMF::AddEdge(num[i][j],t,1,0);}for(int i=0;i<n;i++)MCMF::AddEdge(s,i,INF,0);int flow,cost;MCMF::Min_cost(flow,cost);cost=(cost+res)*(n-3)*8;printf("%d\n",n*(n-1)*(n-2)*(n-3)-cost);}return 0;
}

HDU 6445 2018CCPC网络赛1008 Search for Answer(费用流 + 构图)相关推荐

  1. 【2018ccpc网络赛1008】【hdu6445】Search for Answer 题解

    题目大意 ~~~~~~      有一幅竞赛图(n<=200),其中一些边未定向( s[i][j]=1s[i][j]=1s[i][j]=1 且 s[j][i]=0s[j][i]=0s[j][i] ...

  2. 乌鲁木齐网络赛J题(最小费用最大流模板)

    ACM ICPC 乌鲁木齐网络赛 J. Our Journey of Dalian Ends 2017-09-09 17:24 243人阅读 评论(0) 收藏 举报  分类: 网络流(33)  版权声 ...

  3. hdu 2448 Mining Station on the Sea(最短路+费用流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2448 题意:给你一个由N个港口和M个海上油田构成的连通无向图(给出了图中所有的边和权值),现在给你N个 ...

  4. 2018CCPC网络赛 HDU 6444: G. Neko's loop(线段树)

    Neko's loop Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Tota ...

  5. 2018CCPC网络赛 部分题解

    1001:传送门 dalao的题解:https://www.cnblogs.com/Lin88/p/9537354.html 1002:传送门 dalao的题解:https://www.zybuluo ...

  6. 2018CCPC网络赛

    https://blog.csdn.net/qq_37891604/article/details/82078998 https://blog.csdn.net/qq_37891604/article ...

  7. HDU 6156 2016ICPC网络赛 G: Palindrome Function(数位DP)

    题意: 已知函数f(x, k),如果10进制数x在k进制下是个回文数,那么f(x, k)值为k,否则为1 现给出l, r, x, y, 求出∑∑f(i, j)  (l<=i<=r)  (x ...

  8. 2018ccpc网络赛1010 J - YJJ's Salesman

    又是一道没a的题... YJJ is a salesman who has traveled through western country. YJJ is always on journey. Ei ...

  9. 【计蒜客 - 2019南昌邀请赛网络赛 - I】Max answer(单调栈,RMQ)

    题干: Alice has a magic array. She suggests that the value of a interval is equal to the sum of the va ...

最新文章

  1. 在CentOS 6.9 x86_64的nginx 1.12.2上开启echo-nginx-module模块实录
  2. NC93设计LRU缓存结构
  3. c语言class运行错误,win32 C RegisterClass失败,该如何处理
  4. 二维数组的地址表达方式
  5. EXCEL——批量生成中国各省省会经纬度JSON的一种方法
  6. SAP Spartacus deprecation for 4.0 需要注意的一些事项
  7. 如何在优雅地Spring 中实现消息的发送和消费 1
  8. Eclipse之java虚拟机初始化失败问题已解决
  9. php中头部含义,PHP 常用的header头部定义汇总大全
  10. Raki的读paper小记:Dark Experience for General Continual Learning: a Strong, Simple Baseline
  11. 计算机网络(第7版) - 第五章 运输层 习题答案
  12. esp8266 python 74hc595_十九 ,ESP32 74HC595 的使用
  13. vba mysql 80004005_80004005错误,求高手指点,急,谢谢!
  14. 源于《赘婿》电视剧 拼多多申请“拼刀刀”商标
  15. 苹果开发者账号网页版续费失败支付报错解决办法
  16. 安卓开发之样式和主题的使用与夜间/白天模式的动态转换
  17. 使用Gerber文件生成CNC文件。亚克力,PCB切割教程
  18. socket接收与发送缓冲区大小
  19. python手机号码正确编程_Python。弄清楚如何输入正确的电话号码
  20. VBA宏:outlook收件箱中发件人使用联系人

热门文章

  1. Android实现无预览并且能息屏无限录制
  2. SAP的顾问FICO面试经典
  3. 【DP】 会长晨刷记 校OJ2343
  4. 数学/计算机/人工智能/移动机器人学习网站存储
  5. 一图看懂 RTT 设备层次
  6. idea14字体设置
  7. Mac zsh: command not found 解决
  8. 天嵌A40I平台如何调试10.1寸MIPI屏?这份总结收好!
  9. 第二十一篇 vue组件引入使用
  10. jQuery-jquery封装的ajax使用总结