题意:2个人比赛,每场比赛有得分,每场每人派一支圣兽( brute ,字典翻译为畜生,感觉这里不太符╮(╯▽╰)╭),有攻击力和血条。。。一堆规则。。。

合理安排,让1号人获得最大分数,并尽量不要改变原来出场顺序(1,2,3.。。n),并求出相似度(没改变的场数/n)

思路:显然建二分图,赢的话就连负边,输就是正边,x->y,,再跑 s->t费用流,按题意关键是如何在最大费用情况下,尽量流 i-->i`的边,:扩大主要费用法费用扩大比n稍大倍,这里扩大100倍,那么如果是 i-->i`的边,就费用再-1(最多-n,也不影响总费用),所以最后结果取负后,如果ans<100(相当于是费用流0)输,结果为ans/100,取i-->i`的边个数为 ans%100(自然)。

ps:还调了半天,因为题意没有理解到位!第i场比赛分数,按1号人物的圣兽编号为准!以后一定先看样例!

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int maxv=200;
const int maxe=200*200*2+800;
const int inf=0x3f3f3f3f;
int nume=0;int e[maxe][4];int head[maxv];
int n,m,k;
void inline adde(int i,int j,int c,int w)
{
e[nume][0]=j;e[nume][1]=head[i];head[i]=nume;
e[nume][2]=c;e[nume++][3]=w;
e[nume][0]=i;e[nume][1]=head[j];head[j]=nume;
e[nume][2]=0;e[nume++][3]=-w;
}
int inq[maxv];int pre[maxv];int prv[maxv];
int d[maxv];
int val[maxv];int hi[maxv];int pi[maxv];int ai[maxv];int bi[maxv]; //val该圣兽对应分数(以我方为标准) pi:我方圣兽血,hi敌血,ai我攻击力,bi敌攻击力
bool spfa(int &sum,int &flow)
{
int s=2*n,t=2*n+1;
for(int i=0;i<=t;i++)
{
inq[i]=0;
d[i]=inf;
}
queue<int>q;
q.push(s);
inq[s]=1;
d[s]=0;
while(!q.empty())
{
int cur=q.front();
q.pop();
inq[cur]=0;
for(int i=head[cur];i!=-1;i=e[i][1])
{
int v=e[i][0];
if(e[i][2]>0&&d[cur]+e[i][3]<d[v])
{
d[v]=d[cur]+e[i][3];
pre[v]=i;
prv[v]=cur;
if(!inq[v])
{
q.push(v);
inq[v]=1;
}
}
}
}
if(d[t]==inf)return 0;
int cur=t;
int minf=inf;
while(cur!=s)
{
int fe=pre[cur];
minf=e[fe][2]<minf?e[fe][2]:minf;
cur=prv[cur];
}
cur=t;
while(cur!=s)
{
e[pre[cur]][2]-=minf;
e[pre[cur]^1][2]+=minf;
cur=prv[cur];
}
flow+=minf;
sum+=d[t]*minf;
return 1;
}
int mincost(int &flow)
{
int sum=0;
while(spfa(sum,flow));
return sum;
}
void init()
{
nume=0;
for(int i=0;i<=n*2+2;i++)
head[i]=-1;
}
bool getres(int xph,int xf,int yph,int yf) //使用该匹配能不能赢
{
int count1,count2;
if(xph%yf!=0)
count1=xph/yf+1;
else count1=xph/yf; if(yph%xf!=0)
count2=yph/xf+1;
else count2=yph/xf;
if(count1>=count2)return 1;
else return 0;
}
void read_build()
{
for(int j=0;j<n;j++)
scanf("%d",&val[j]);
for(int j=0;j<n;j++)
scanf("%d",&hi[j]);
for(int j=0;j<n;j++)
scanf("%d",&pi[j]);
for(int j=0;j<n;j++)
scanf("%d",&ai[j]);
for(int j=0;j<n;j++)
scanf("%d",&bi[j]); for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(getres(hi[i],ai[i],pi[j],bi[j]))
{
if(i!=j) // 相等情况下,费用-1
adde(i,j+n,1,-val[i]*100);
else
adde(i,j+n,1,-val[i]*100-1);
}
else
{
if(i!=j)
adde(i,j+n,1,val[i]*100);
else
adde(i,j+n,1,val[i]*100-1);
}
}
for(int i=0;i<n;i++)
{
adde(2*n,i,1,0);
adde(i+n,2*n+1,1,0);
}
/* for(int i=0;i<=2*n+1;i++)
for(int j=head[i];j!=-1;j=e[j][1])
{
printf("%d->%d:f %dw %d\n",i,e[j][0],e[j][2],e[j][3]);
}*/ }
int main()
{
while(~scanf("%d",&n)&&n!=0)
{
init();
read_build();
int flow=0;
int ans=-mincost(flow);
if(ans<100) //这里是<100,因为现在已经取反!
printf("Oh, I lose my dear seaco!\n");
else
printf("%d %.3f%%\n",ans/100,(ans%100)*1.0/n*100); }
return 0;
}

hdu3315 /最大权最佳匹配(最大权下尽量不改变次序)(有权田忌赛马类问题)/费用流的更多相关文章

  1. vi或vim下按方向键改变方向变成ABCD这类字符

    遇到这种问题肯定很恼火,按方向键改变文本的方向有时候变成输入ABCD,有时候并不是我们想要的结果 解决方法: $ echo "set nocp" >> ~/.vimrc ...

  2. HDU3315 费用流

    为了不让颓影响到学习= = (主要是颓得不想敲代码) 所以,决定在OJ上随便挑一题,能搞便搞,不会就找题解,扒过来,认真研究......(比如这题 原帖:http://m.blog.csdn.net/ ...

  3. 【模板】二分图最大权完美匹配KM算法

    hdu2255模板题 KM是什么意思,详见百度百科. 总之知道它可以求二分图最大权完美匹配就可以了,时间复杂度为O(n^3). 给张图. 二分图有了边权,求最大匹配下的最大权值. 所以该怎么做呢?对啊 ...

  4. HDU 1533 Going Home (最大权完美匹配)

    <题目链接> 题目大意:给你一张地图,地图上m代表人,H代表房子,现在所有人要走到房子内,且一个房子只能容纳一个人(人和房子的数量相同),人每移动一步,需要花1美元,问所有人走到房子中的最 ...

  5. HDU 3488 Tour (最大权完美匹配)【KM算法】

    <题目链接> 题目大意:给出n个点m条单向边边以及经过每条边的费用,让你求出走过一个哈密顿环(除起点外,每个点只能走一次)的最小费用.题目保证至少存在一个环满足条件. 解题分析: 因为要求 ...

  6. 二分图学习记 之 KM算法 二分图最大权完美匹配。

    前置知识 :匈牙利算法 首先有这样一张图,求这张图的最大权完美匹配. 当然如果你不想看这些渣图的话,您可以转到 洛谷 运动员最佳匹配问题 下面我来强行解释一下KM算法 左边一群妹子找汉子,但是每个妹子 ...

  7. Solution -「洛谷 P6577」「模板」二分图最大权完美匹配

    \(\mathcal{Description}\)   Link.   给定二分图 \(G=(V=X\cup Y,E)\),\(|X|=|Y|=n\),边 \((u,v)\in E\) 有权 \(w( ...

  8. POJ2195 Going Home[费用流|二分图最大权匹配]

    Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22088   Accepted: 11155 Desc ...

  9. HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法

    二分图最大权值匹配问题.用KM算法. 最小权值的时候把权值设置成相反数 /*-------------------------------------------------------------- ...

随机推荐

  1. 漫谈 Clustering (4): Spectral Clustering<转载>

    转自http://blog.pluskid.org/?p=287 如果说 K-means 和 GMM 这些聚类的方法是古代流行的算法的话,那么这次要讲的 Spectral Clustering 就可以 ...

  2. CentOS 7.0关闭防火墙

    .关闭firewall: systemctl stop firewalld.service #停止firewall systemctl disable firewalld.service #禁止fir ...

  3. 2017年网络空间安全技术大赛部分writeup

    作为一个bin小子,这次一个bin都没做出来,我很羞愧. 0x00 拯救鲁班七号 具体操作不多说,直接进入反编译源码阶段 可以看到,只要2处的str等于a就可以了,而str是由1处的checkPass ...

  4. A*和IDA*介绍

    \(A*\)算法是一种很神奇的搜索方法,它属于启发式搜索中的一种.A*最主要的功能当然就是用来剪枝,提高搜索的效率.A*主要的实现方法是通过一个估价函数,每次对下一步进行一个估价,根据估价出的值来决定 ...

  5. Bootstrap历练实例:块级按钮

    <!DOCTYPE html><html><head> <meta http-equiv="Content-Type" content=& ...

  6. CS193p Lecture 11 - UITableView, iPad

    UITableView 的 dataSource 和 delegate dataSource 是一种协议,由 UITableView 实现,将 Model 的数据给到 UITableView: del ...

  7. '>>' should be '> >' within a nested template argument list

    在编译关于opencv相机标定的工程的时候出现了这个问题 vector<vector<Point3f>>  objectPoints;  error: 'objectPoint ...

  8. ServletResponse使用方法

    Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象 request和response对象即然代表请求和响应,那我们要 ...

  9. 大数据学习——sqoop安装

    1上传  sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz 2解压 .bin__hadoop--alpha.tar.gz 3重命名 .bin__hadoop--al ...

  10. BNU OJ 1027 金币系统

    金币系统 Time Limit: 1000ms Memory Limit: 65535KB   64-bit integer IO format: %lld      Java class name: ...