题面:

  有N个人参加一场比赛,赛程规定任意两个人之间都要进行一场比赛:这样总共有N*(N-1)/2场比赛。比赛已经进行了一部分,我们想知道在极端情况下,比赛结束后最多会发生多少剪刀石头布情况。即给出已经发生的比赛结果,而你可以任意安排剩下的比赛的结果,以得到尽量多的剪刀石头布情况。
  剪刀石头布情况,即无序三元组(A, B, C),满足其中的一个人在比赛中赢了另一个人,另一个人赢了第三个人而第三个人又胜过了第一个人。

分析:

  把题意转化一下,就是给定了一张有向完全图的残本,剩下的边你可以任意安排,求出现最多的三元环数量。

  我们可以用一下小小的容斥,假如我们任选三个点,方案数是C(n,3),我们就找出最少失去的三元环数量,就可以给出这个题的答案了。

  根据《一眼看出法》,我们可以了解,假如一个点x的入度(以下简称in[x])为w,那么它会使整个图失去的三元环数量为C(w,2)。

  即:如果一个点的入度增加1,会使三元环数量减少in[x]-1这么多。所以我们需要尽量保证不会出现某个点入度特别多,换句话说就是尽量让入度平均。(这大概就是题解中说的凸函数的性质???)

  所以,我们将失去的三元环作费用,跑费用流。

  对于未定向的边,我们将其抽象成点(这里原图中的点也被抽象成点)

  我们由源点S向每条未定向的边对应的点连边,容量为1费用为0;

  对于每条被我们建成点的边,我们从这个点向这条边连通的两个点连边,容量为1,费用为0,表示这条边会给其中一个点带来入度加一的贡献。

  对于每个原图上的节点x,我们想汇点T连接若干条边,容量都为1,费用分别为in[x], in[x]+1, in[x]+2,…,n-2(表示每增加1个单位的流量,就会带来这么多三元环的毁灭。想想为什么最大是n-2?)

  之后定向方案,看边对应的点哪条出边满流即可!

代码:

 #include<bits/stdc++.h>
using namespace std;
const int N=,inf=0x3f3f3f3f;int f[N];
struct node{int y,z,f,nxt;}e[N*];int lst[N];
int n,S,T,tot,g[][],dg[N],tmp[N],X[N],Y[N];
int h[N],c=,d[N],vis[N],pre[N],ans;queue<int>q;
void add(int x,int y,int l,int z){
e[++c]=(node){y,z,l,h[x]};h[x]=c;
e[++c]=(node){x,-z,,h[y]};h[y]=c;
} bool spfa(){
for(int i=S;i<=T;i++) pre[i]=-,
f[i]=inf,lst[i]=vis[i]=,d[i]=inf;
q.push(S);d[S]=;pre[S]=;
while(!q.empty()){
int x=q.front();q.pop();vis[x]=;
for(int i=h[x],y;~i;i=e[i].nxt)
if(d[y=e[i].y]>d[x]+e[i].z&&e[i].f){
d[y]=d[x]+e[i].z;pre[y]=x;lst[y]=i;
f[y]=min(f[x],e[i].f);
if(!vis[y]) vis[y]=,q.push(y);
}
} return pre[T]!=-;
} void solve(){
while(spfa()){
ans+=d[T]*f[T];int x=T;
while(x) e[lst[x]].f-=f[T],
e[lst[x]^].f+=f[T],x=pre[x];
} return ;
} int main(){
memset(h,-,sizeof(h));
scanf("%d",&n);S=,tot=n;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++){
scanf("%d",&g[i][j]);
if(g[i][j]==){
if(i>j) continue;
X[++tot]=i,Y[tot]=j;
add(S,tot,,);
add(tot,i,,);
add(tot,j,,);
tmp[i]++;tmp[j]++;
} else dg[i]+=g[i][j];
} T=++tot;for(int i=;i<=n;i++){
ans+=(dg[i]*dg[i]-dg[i])/;
for(int j=dg[i]+;j<n;j++)
add(i,T,,j-);
} solve();int tt=n*(n-)*(n-)/;
printf("%d\n",tt-ans);
for(int i=n+,v;i<tot;i++){
for(int p=h[i];~p;p=e[p].nxt)
if(e[p].y!=S&&!e[p].f)
{v=e[p].y;break;}
if(v==X[i]) g[X[i]][Y[i]]=,
g[Y[i]][X[i]]=;
else g[X[i]][Y[i]]=,g[Y[i]][X[i]]=;
} for(int i=;i<=n;i++,puts(""))
for(int j=;j<=n;j++)
printf("%d ",g[i][j]);return ;
}

费用流

WC2007 石头剪刀布 数学+最小费用最大流的更多相关文章

  1. BZOJ2597 [Wc2007]剪刀石头布(最小费用最大流)

    题目大概是说n个人两两进行比赛,问如何安排几场比赛的输赢使得A胜B,B胜C,C胜A这种剪刀石头布的三元组最多. 这题好神. 首先,三元组总共有$C_n^3$个 然后考虑最小化不满足剪刀石头布条件的三元 ...

  2. bzoj 2597: [Wc2007]剪刀石头布【最小费用最大流】

    脑子不太清楚一个zz问题调了好久-- 首先正难则反,因为三元环好像没什么特点,就考虑让非三元环个数最小 考虑非三元环特点,就是环上一定有一个点的入度为2,联系整张图,三元环个数就是每个点C(入度,2) ...

  3. HDU5988/nowcoder 207G - Coding Contest - [最小费用最大流]

    题目链接:https://www.nowcoder.com/acm/contest/207/G 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5988 ...

  4. [板子]最小费用最大流(Dijkstra增广)

    最小费用最大流板子,没有压行.利用重标号让边权非负,用Dijkstra进行增广,在理论和实际上都比SPFA增广快得多.教程略去.转载请随意. #include <cstdio> #incl ...

  5. bzoj1927最小费用最大流

    其实本来打算做最小费用最大流的题目前先来点模板题的,,,结果看到这道题二话不说(之前打太多了)敲了一个dinic,快写完了发现不对 我当时就这表情→   =_=你TM逗我 刚要删突然感觉dinic的模 ...

  6. ACM/ICPC 之 卡卡的矩阵旅行-最小费用最大流(可做模板)(POJ3422)

    将每个点拆分成原点A与伪点B,A->B有两条单向路(邻接表实现时需要建立一条反向的空边,并保证环路费用和为0),一条残留容量为1,费用为本身的负值(便于计算最短路),另一条残留容量+∞,费用为0 ...

  7. HDU5900 QSC and Master(区间DP + 最小费用最大流)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5900 Description Every school has some legends, ...

  8. P3381 【模板】最小费用最大流

    P3381 [模板]最小费用最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行 ...

  9. 【BZOJ-3876】支线剧情 有上下界的网络流(有下界有源有汇最小费用最大流)

    3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 821  Solved: 502[Submit][Status ...

随机推荐

  1. CodeForces 730H Delete Them (暴力)

    题意:给定n个名字,然后让你删除 m 个,且这m个必须满足同一个表达式且其他的不满足,问你能不能找到一个满足条件. 析:很明显首先知道的是这 m 个如果第 i 个位置相同,那么就肯定选这个位置是最好的 ...

  2. ubuntu下7z文件的解压方法(转载)

    转自:http://qtlinux.blog.51cto.com/3052744/569406 打开终端,键入以下命令: apt-get install p7zip-full 控制台会打出以下信息: ...

  3. bzoj 2986: Non-Squarefree Numbers【容斥+莫比乌斯函数】

    看到\( 10^10 \)的范围首先想到二分,然后把问题转化为判断\( [1,n] \)内有多少个是某个质数的平方和的数. 所以应该是加上是一个质数的平方的个数减去是两个质数的平方的个数加上是三个质数 ...

  4. bzoj 1070: [SCOI2007]修车【最小费用最大流】

    一开始从客人角度想的,怎么建都不对 从一个修车工所接待的所有顾客花费的总时间来看,设一共有x个人,那么第一个修的对总时间的贡献是x*w1,第二个是(x-1)*w2-以此类推.所以把第i个修车工拆成n组 ...

  5. 11.3NOIP模拟赛

    /* 考虑贪心 把原序列排序后,对于原中位数往后所有比要更改到的值小的都改成它 正确性显然. */ #include<iostream> #include<cstdio> #i ...

  6. Luogu P1970 花匠 【线性Dp】 By cellur925

    题目描述 Description 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希望剩下的花 ...

  7. python数据库连接例子

    import sqlite3 conn = sqlite3.connect('food.db') curs = conn.cursor() curs.execute(''' CREATE TABLE ...

  8. Linux的防火墙概念

    #linux的防火墙概念#因为如果你不关防火墙,很可能运行 django.nginx.mysql出错#防火墙可能会阻挡端口流量的 出口#也会阻挡外来请求的 入口 #selinux iptables f ...

  9. _bzoj1497 [NOI2006]最大获利【最大权闭合子图】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1497 保存最大流模版. 选一个用户群,就必须要选对应的两个中转站,这种关系类似“最大全闭合子 ...

  10. fastboot命令详解

    Android手机分区(每个分区都有相应的img文件对应):开机启动画面区(splash1),数据恢复区(recovery),内核区(boot), 系统区(system),数据缓存区(cache),用 ...