权限题qwq

如果我们要使得某棵生成树为最小生成树,那么上面的边都不能被替代,具体的,对于一个非树边,它的权值要\(\ge\)它两端点在树上的路径上的所以边的权值,所以对于每个非树边就可以对一些树边列出不等关系,并且显然要把树边减小边权,非树边增加边权才会更优,所以记树边减少量为\(dt_a\),非树边增加量为\(dt_b\),就可以改写成不等式\(dt_a+dt_b\ge \max(w_a-w_b,0)\).那么问题变成若干变量,每个变量每增加\(1\)要付出一定代价,求最小代价满足所有不等式

这个不等式的形式有点不好下手,考虑这个问题的对偶问题,这等价于对于每个不等式\(i\)确定一个非负权值,每有一个权值获得\(max(w_a-w_b,0)\)的收益,同时满足权值\(\le\)对应树边和非树边修改一次的代价,求最大收益.那么可以网络流解决,\(S\)向所有树边连容量/费用为\((c_a,0)\)的边,非树边向\(T\)连\((c_b,0)\)的边,有不等式关系的一组边连\((+\infty,max(w_a-w_b,0))\)的边,然后最大费用流即可

#include<bits/stdc++.h>
#define LL long long
#define uLL unsigned long long
#define db double using namespace std;
const int N=2000+10,M=N*100,inf=1<<30;
int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int to[M],nt[M],c[M],w[M],hd[N],tot=1;
void add(int x,int y,int z,int zz)
{
++tot,to[tot]=y,nt[tot]=hd[x],c[tot]=z,w[tot]=zz,hd[x]=tot;
++tot,to[tot]=x,nt[tot]=hd[y],c[tot]=0,w[tot]=-zz,hd[y]=tot;
}
int ps,pt,di[N],fw[N],pr[N],cst;
bool v[N];
queue<int> q;
bool csfl()
{
for(int i=0;i<=pt;++i) di[i]=inf;
di[ps]=0,fw[ps]=inf,fw[pt]=0,v[ps]=1,q.push(ps);
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(c[i]>0&&di[y]>di[x]+w[i])
{
di[y]=di[x]+w[i];
fw[y]=min(fw[x],c[i]),pr[y]=i;
if(!v[y]) v[y]=1,q.push(y);
}
}
v[x]=0;
}
if(!fw[pt]||di[pt]>=0) return 0; //边权取反做最大费用流,增广的权值不优就停止
cst+=di[pt]*fw[pt];
int x=pt;
while(x!=ps)
{
int i=pr[x];
c[i]-=fw[pt],c[i^1]+=fw[pt];
x=to[i^1];
}
return 1;
}
int n,m,ee[N][2],ew[N],cs[N],fa[N],pre[N],de[N];
bool fg[N];
void dd(int x)
{
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y==fa[x]) continue;
if(fg[i>>1]) fa[y]=x,pre[y]=i>>1,de[y]=de[x]+1,dd(y);
}
}
void link(int i,int j)
{
int ss=max(0,ew[i]-ew[j]);
add(i,j,inf,-ss);
} int main()
{
freopen("3118.in","r",stdin);
freopen("3118.out","w",stdout);
n=rd(),m=rd();
for(int i=1;i<=m;++i)
{
int x=rd(),y=rd();
add(ee[i][0]=x,ee[i][1]=y,0,0);
ew[i]=rd(),fg[i]=rd();
if(fg[i]) rd(),cs[i]=rd();
else cs[i]=rd(),rd();
}
de[1]=1,dd(1);
memset(hd,0,sizeof(int)*(n+3)),tot=1;
ps=0,pt=m+2;
for(int i=1;i<=m;++i)
{
if(fg[i]) add(ps,i,cs[i],0);
else
{
add(i,pt,cs[i],0);
int x=ee[i][0],y=ee[i][1];
if(de[x]<de[y]) swap(x,y);
while(de[x]>de[y]) link(pre[x],i),x=fa[x];
while(x!=y)
{
link(pre[x],i),x=fa[x];
link(pre[y],i),y=fa[y];
}
}
}
while(csfl());
printf("%d\n",-cst);
return 0;
}

BZOJ 3118 Orz the MST的更多相关文章

  1. bzoj 3118: Orz the MST(单纯形)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3118 题意:给出一个图以及图中指定的n-1条边组成的生成树.每条边权值加1或者减去 ...

  2. BZOJ 2654 & 玄学二分+MST

    题意: 给一张图,边带权且带颜色黑白,求出一棵至少包含k条白边的MST SOL: 正常人都想优先加黑边或者是白边,我也是这么想的...你看先用白边搞一棵k条边的MST...然后维护比较黑边跟白边像堆一 ...

  3. BZOJ3118 : Orz the MST

    对于树边显然只需要减少权值,对于非树边显然只需要增加权值 设i不为树边,j为树边 X[i]:i增加量 X[j]:j减少量 C[i]:修改1单位i的代价 对于每条非树边i(u,v),在树上u到v路径上的 ...

  4. BZOJ 2654: tree( 二分 + MST )

    我们给白色的边增加权值 , 则选到的白色边就会变多 , 因此可以二分一下. 不过这道题有点小坑... ------------------------------------------------- ...

  5. BZOJ3118 Orz the MST 【单纯形 + 生成树】

    题目链接 BZOJ3118 题解 少有的单纯形好题啊 我们先抽离出生成树 生成树中的边只可能减,其它边只可能加 对于不在生成树的边,其权值一定要比生成树中其端点之间的路径上所有的边都大 然后就是一个最 ...

  6. bzoj3118: Orz the MST(线性规划+单纯形法)

    传送门 不难发现,对于每一条树边肯定要减小它的权值,对于每一条非树边要增加它的权值 对于每一条非树边\(j\),他肯定与某些树边构成了一个环,那么它的边权必须大于等于这个环上的所有边 设其中一条边为\ ...

  7. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  8. BZOJ4652 [Noi2016]循环之美 【数论 + 莫比乌斯反演 + 杜教筛】

    题目链接 BZOJ 题解 orz 此题太优美了 我们令\(\frac{x}{y}\)为最简分数,则\(x \perp y\)即,\(gcd(x,y) = 1\) 先不管\(k\)进制,我们知道\(10 ...

  9. luogu4169 [Violet]天使玩偶/SJY摆棋子 / bzoj2648 SJY摆棋子 k-d tree

    k-d tree + 重构的思想,就能卡过luogu和bzoj啦orz #include <algorithm> #include <iostream> #include &l ...

随机推荐

  1. spring-boot 中实现标准 redis 分布式锁

    一,前言 redis 现在已经成为系统缓存的必备组件,针对缓存读取更新操作,通常我们希望当缓存过期之后能够只有一个请求去更新缓存,其它请求依然使用旧的数据.这就需要用到锁,因为应用服务多数以集群方式部 ...

  2. C++入门经典-例5.3例5.4-输出int指针运算后的地址值

    1:代码如下: // 5.3.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> using ...

  3. HearthBuddy 第一次调试

    HearthBuddy https://www.jiligame.com/70639.html 解压缩包,打开hearthbuddy.exe直接运行就可以:不用替换mono.dll直接可用:不需要校验 ...

  4. HANA LOG日志过大处理办法

    http://www.fenxiangzhe.net/archives/50 在SAP HANA 运维过程我们经常遇到因前期HANA LOG模式未设置成OVERWIRTE或者日志备份时间设置过长导致日 ...

  5. DeepFaceLab: 可视化交互式合成功能简介!

    DeepFaceLab在沉寂了几个月后(目测Iperov同志讨生活去了),在8月下旬又迎来了重大更新.我总结了一下,主要是更新了三大功能. 新增Avatar模型 交互式转换器 半脸模型支持FAN ​ ...

  6. Switch 开关

    表示两种相互对立的状态间的切换,多用于触发「开/关」. 基本用法 绑定v-model到一个Boolean类型的变量.可以使用active-color属性与inactive-color属性来设置开关的背 ...

  7. Dart 基本语法

    ?? // 如果b为null则赋值,否则保持原样 b ??= value; 级联符号.. querySelector('#confirm') // Get an object. ..text = 'C ...

  8. linux 下的快捷键操作

    概述 今天发现自己码代码的效率有点低,所以查找了一下 linux 常用的快捷键操作,记录下来,供以后开发时参考,相信对其他人也有用. linux 终端常用快捷键 tab:补全命令 Ctrl + u:剪 ...

  9. Web(八) commons-fileupload上传下载

    在网上看见一篇不错的文章,写的详细. 以下内容引用那篇博文.转载于<http://www.cnblogs.com/whgk/p/6479405.html>,在此仅供学习参考之用. 一.上传 ...

  10. Linux 的路由功能

    目录 文章目录 目录 前文列表 路由器 Router 路由 Routing 静态路由与动态路由 通过路由实现的全网通信示例 Linux 作为路由器 route 指令 路由表项的类型 ip route ...