BZOJ

洛谷

裸01分数规划。二分之后就是裸最大费用最大流了。

写的朴素SPFA费用流,洛谷跑的非常快啊,为什么有人还T成那样。。

当然用二分也很慢,用什么什么迭代会很快。

[Update] 19.2.15

下午写的zkw费用流在BZOJ上T了= =

然而在洛谷上和以前写的跑的差不多快

当然还可以写整数二分或者KM...

输出的时候最好加个eps,不然可以被卡比如BZOJ discuss里的数据。


第一次写的代码:

//3624kb	4016ms
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
#define eps 1e-7
#define INF 1e14
const int N=205,M=90000; int n,src,des,Enum,H[N],to[M],fr[M],nxt[M],cap[M],pre[N];
bool inq[N];
double Ans,dis[N],A[N][N],B[N][N],cost[M];
std::queue<int> q; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AddEdge(int u,int v,int w,double c)
{
to[++Enum]=v, nxt[Enum]=H[u], fr[Enum]=u, H[u]=Enum, cap[Enum]=w, cost[Enum]=c;
to[++Enum]=u, nxt[Enum]=H[v], fr[Enum]=v, H[v]=Enum, cap[Enum]=0, cost[Enum]=-c;
}
bool SPFA()
{
for(int i=1; i<=des; ++i) dis[i]=-INF;
q.push(src), dis[src]=0;
while(!q.empty())
{
int x=q.front();q.pop();
inq[x]=0;
for(int v,i=H[x]; i; i=nxt[i])
if(dis[to[i]]<dis[x]+cost[i] && cap[i])
{
dis[v=to[i]]=dis[x]+cost[i], pre[v]=i;
if(!inq[v]) inq[v]=1,q.push(v);
}
}
return dis[des]>-INF;
}
void MCMF(){
for(int i=des; i!=src; i=fr[pre[i]])
--cap[pre[i]], ++cap[pre[i]^1], Ans+=cost[pre[i]];
}
bool pre_Check(double C)
{
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j)
/*if(i!=j) j是女生,不是自己。。*/
AddEdge(i,j+n,1,A[i][j]-C*B[i][j]);
for(int i=1; i<=n; ++i) AddEdge(src,i,1,0),AddEdge(i+n,des,1,0);
Ans=0;
while(SPFA()){
MCMF();
if(Ans<0) break;
}
return Ans>=0;
}
bool Check(double C)
{
int cnt=1;
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j)
cap[++cnt]=1, cost[cnt]=A[i][j]-C*B[i][j], cap[++cnt]=0, cost[cnt]=-A[i][j]+C*B[i][j];
for(int i=1; i<=n; ++i)
cap[++cnt]=1, cost[cnt]=0, cap[++cnt]=0, cost[cnt]=0,
cap[++cnt]=1, cost[cnt]=0, cap[++cnt]=0, cost[cnt]=0;
Ans=0;
while(SPFA()){
MCMF();
if(Ans<0) break;
}
return Ans>=0;
} int main()
{
n=read(),Enum=1,src=0,des=n<<1|1;
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j) A[i][j]=read();
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j) B[i][j]=read();
double l=0,r=10000.0,mid;
if(pre_Check(mid=(l+r)*0.5)) l=mid;
else r=mid;
while(r>l+eps)
if(Check(mid=(l+r)*0.5)) l=mid;
else r=mid;
printf("%.6lf",l+eps); return 0;
}

第二次写的代码:(BZOJ上T掉的zkw= =)

#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define eps 1e-7
#define gc() getchar()
typedef long long LL;
const int N=207,M=(N*N+N)*2;
const double INF=1ll<<61; int T,Enum,cur[N],H[N],to[M],nxt[M],cap[M],A[103][103],B[103][103];
bool vis[N];
double Cost,cost[M],dis[N]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
}
inline void AE(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
void PreBuild(int n)
{
Enum=1;
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j) AE(i,j+n);
for(int i=1; i<=n; ++i) AE(0,i), AE(i+n,T);
}
bool BFS()
{
static bool inq[N];
static std::queue<int> q;
for(int i=1; i<=T; ++i) dis[i]=-INF;
q.push(0), dis[0]=0;
while(!q.empty())
{
int x=q.front(); q.pop();
inq[x]=0;
for(int i=H[x],v; i; i=nxt[i])
if(dis[v=to[i]]<dis[x]+cost[i] && cap[i])
dis[v]=dis[x]+cost[i], !inq[v]&&(q.push(v),inq[v]=1);
}
return dis[T]>-INF;
}
bool DFS(int x)
{
if(x==T) return 1;
vis[x]=1;//!!
for(int &i=cur[x]; i; i=nxt[i])
if(!vis[to[i]] && cap[i] && dis[to[i]]==dis[x]+cost[i] && DFS(to[i]))
return --cap[i], ++cap[i^1], Cost+=cost[i], 1;
return 0;
}
bool MCMF()
{
Cost=0;
while(BFS())
{
memset(vis,0,T+1), memcpy(cur,H,T+1<<2);
while(DFS(0) && Cost>=0);
if(Cost<0) break;
}
return Cost>=0;
}
bool Check(int n,double x)
{
int now=1;
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j)
cap[++now]=1, cost[now]=A[i][j]-x*B[i][j], cap[++now]=0, cost[now]=-cost[now-1];
for(int i=1; i<=n; ++i) cap[++now]=1, cap[++now]=0, cap[++now]=1, cap[++now]=0;
return MCMF();
} int main()
{
freopen("ball.in","r",stdin);
freopen("ball.out","w",stdout); int n=read(); T=n+n+1;
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j) A[i][j]=read();
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j) B[i][j]=read();
PreBuild(n);
double l=0,r=1e4+1e-4,mid;
while(l+eps<r)
if(Check(n,mid=(l+r)*0.5)) l=mid;
else r=mid;
printf("%.6lf\n",l+eps); return 0;
}

BZOJ.4819.[SDOI2017]新生舞会(01分数规划 费用流SPFA)的更多相关文章

  1. 【BZOJ4819】[Sdoi2017]新生舞会 01分数规划+费用流

    [BZOJ4819][Sdoi2017]新生舞会 Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会 买一个男生和一个女 ...

  2. P3705 [SDOI2017]新生舞会 01分数规划+费用流

    $ \color{#0066ff}{ 题目描述 }$ 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴. 有\(n\)个男生和\(n\)个女生参加舞会买一个男生和一个女生一 ...

  3. BZOJ_4819_[Sdoi2017]新生舞会_01分数规划+费用流

    BZOJ_4819_[Sdoi2017]新生舞会_01分数规划+费用流 Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞 ...

  4. BZOJ-4819: 新生舞会(01分数规划+费用流)

    Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会 买一个男生和一个女生一起跳舞,互为舞伴.Cathy收集了这些同学之间 ...

  5. [Sdoi2017]新生舞会(分数规划+费用流)

    题解:二分答案mid,然后将每个位置看成a-b*mid,然后由于是n个男生和n个女生匹配,每个人搭配一个cp,于是有点类似于https://www.lydsy.com/JudgeOnline/prob ...

  6. 4819: [Sdoi2017]新生舞会(分数规划)

    4819: [Sdoi2017]新生舞会 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1031  Solved: 530[Submit][Statu ...

  7. [Sdoi2017]新生舞会 [01分数规划 二分图最大权匹配]

    [Sdoi2017]新生舞会 题意:沙茶01分数规划 貌似\(*10^7\)变成整数更科学 #include <iostream> #include <cstdio> #inc ...

  8. BZOJ4819: [Sdoi2017]新生舞会(01分数规划)

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1029  Solved: 528[Submit][Status][Discuss] Descripti ...

  9. bzoj 4819: [Sdoi2017]新生舞会【二分+最小费用最大流】

    如果\( b[i]==0 \)那么就是裸的费用流/KM,当然KM快一些但是为什么不写KM呢因为我不会打板子了 考虑二分答案,那么问题变成了判定问题. \[ ans=\frac {a_1+a_2+... ...

随机推荐

  1. 优雅地搭建整合ssm项目

    spring + spring mvc + mybatis 三大框架建议观看 黑马程序员出品的 Springmvc+Mybatis由浅入深全套视频教程 Spring框架2016版视频 观看顺序 ,我个 ...

  2. ASP.NET Web API queryString访问的一点总结

    自从开始使用ASP.NET Web API,各种路由的蛋疼问题一直困扰着我,相信大家也都一样. Web API的路由配置与ASP.MVC类似,在App_Start文件夹下,有一个WebApiConfi ...

  3. java CyclicBarrier以及和CountDownLatch的区别

    CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier).让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的 ...

  4. linux - JDK 环境

    JDK安装 vi /etc/profile # 添加环境变量 export JAVA_HOME=/usr/local/jdk1.8.2_45 export CLASSPATH=.:$JAVA_HOME ...

  5. FinalShell 推荐

    FinalShell是一体化的的服务器,网络管理软件,不仅是ssh客户端,还是功能强大的开发,运维工具,充分满足开发,运维需求. 用户QQ群 342045988 Windows版下载地址:http:/ ...

  6. [HAOI2008]移动玩具(状压&带权二分图)

    题目描述 • 一个 4 × 4 的 0/1 矩阵 • 每次可以交换相邻两个元素 • 求从初始状态到目标状态的最小交换次数 输入格式 前四行,每行一个长为 4 的 0/1 字符串,描述初始状态. 后四行 ...

  7. FPGA学习笔记. 二分频和三分频

    二分频和三分频 二分频:将输入频率CLK分为原来的 1/2 . 实现:在每次CLK的上升沿或下降沿将输出翻转. 三分频: 1/3占空比. 实现:可使用上升沿或下降沿计数生成输出.需要一个两位计数器. ...

  8. TrID文件类型识别linux版

    读取文件头根据特征码进行文件类型匹配. 官方:http://mark0.net/soft-trid-e.html windows版本小工具:FileAnalysis 以下是linux版本 wget h ...

  9. 解读Android LOG机制的实现【转】

    转自:http://www.cnblogs.com/hoys/archive/2011/09/30/2196199.html http://armboard.taobao.com/ Android提供 ...

  10. c# XML读取

    System.Xml 命名空间 https://msdn.microsoft.com/zh-cn/library/gg145036(v=vs.110).aspx 一.读取 1.通过 XmlDocume ...