hdu3315 /最大权最佳匹配(最大权下尽量不改变次序)(有权田忌赛马类问题)/费用流
题意: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 /最大权最佳匹配(最大权下尽量不改变次序)(有权田忌赛马类问题)/费用流的更多相关文章
- vi或vim下按方向键改变方向变成ABCD这类字符
遇到这种问题肯定很恼火,按方向键改变文本的方向有时候变成输入ABCD,有时候并不是我们想要的结果 解决方法: $ echo "set nocp" >> ~/.vimrc ...
- HDU3315 费用流
为了不让颓影响到学习= = (主要是颓得不想敲代码) 所以,决定在OJ上随便挑一题,能搞便搞,不会就找题解,扒过来,认真研究......(比如这题 原帖:http://m.blog.csdn.net/ ...
- 【模板】二分图最大权完美匹配KM算法
hdu2255模板题 KM是什么意思,详见百度百科. 总之知道它可以求二分图最大权完美匹配就可以了,时间复杂度为O(n^3). 给张图. 二分图有了边权,求最大匹配下的最大权值. 所以该怎么做呢?对啊 ...
- HDU 1533 Going Home (最大权完美匹配)
<题目链接> 题目大意:给你一张地图,地图上m代表人,H代表房子,现在所有人要走到房子内,且一个房子只能容纳一个人(人和房子的数量相同),人每移动一步,需要花1美元,问所有人走到房子中的最 ...
- HDU 3488 Tour (最大权完美匹配)【KM算法】
<题目链接> 题目大意:给出n个点m条单向边边以及经过每条边的费用,让你求出走过一个哈密顿环(除起点外,每个点只能走一次)的最小费用.题目保证至少存在一个环满足条件. 解题分析: 因为要求 ...
- 二分图学习记 之 KM算法 二分图最大权完美匹配。
前置知识 :匈牙利算法 首先有这样一张图,求这张图的最大权完美匹配. 当然如果你不想看这些渣图的话,您可以转到 洛谷 运动员最佳匹配问题 下面我来强行解释一下KM算法 左边一群妹子找汉子,但是每个妹子 ...
- Solution -「洛谷 P6577」「模板」二分图最大权完美匹配
\(\mathcal{Description}\) Link. 给定二分图 \(G=(V=X\cup Y,E)\),\(|X|=|Y|=n\),边 \((u,v)\in E\) 有权 \(w( ...
- POJ2195 Going Home[费用流|二分图最大权匹配]
Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 22088 Accepted: 11155 Desc ...
- HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法
二分图最大权值匹配问题.用KM算法. 最小权值的时候把权值设置成相反数 /*-------------------------------------------------------------- ...
随机推荐
- CPP-网络/通信:POST
BOOL PostSubmit(CString strUrl,const CString&strPara, CString&strContent){ BOOL bRet=FALSE; ...
- Linux文件操作函数
creat() 函数 close() 函数 read() 函数 read 函数实际读到的字节数少于要求读的字节数时: 读普通文件,在读到要求字节数之前就到达文件尾: 当从终端设备读,通常一次最多读一行 ...
- Bootstrap历练实例:基本按钮群组
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- 任务十一:移动Web页面布局实践
面向人群: 有一定HTML及CSS基础,想要尝试移动开发 难度: 中 重要说明 百度前端技术学院的课程任务是由百度前端工程师专为对前端不同掌握程度的同学设计.我们尽力保证课程内容的质量以及学习难度的合 ...
- kvm虚拟迁移
1. 虚拟迁移 迁移: 系统的迁移是指把源主机上的操作系统和应用程序移动到目的主机,并且能够在目的主机上正常运行.在没有虚拟机的时代,物理机之间的迁移依靠的是系统备份和恢复技术.在源主机上实时备份操作 ...
- netfilter 和 iptables
http://blog.chinaunix.net/uid/23069658/cid--1-list-4.html 洞悉linux下的Netfilter&iptables 系列,有一到十六, ...
- 【Linux】启动Tomcat遇到Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
找不到JAVA_HOME路径,需要做以下变更: 找到启动路径所在的目录: cd bin/ vi catalina.sh 加入以下信息: export JAVA_HOME=/home/gongzi/ht ...
- element使用心得
Table Table 常用属性解释 数据过滤,filter过滤器 <el-table-column width="200" show-overflow-tooltip la ...
- verilog behavioral modeling--blocking and nonblocking
BLOCKIN ...
- verilog behavioral modeling --procedural assignments
1.procedural assignments are used for updating reg ,integer , time ,real,realtime and memory data ty ...