BZOJ 1937: [Shoi2004]Mst 最小生成树 [二分图最大权匹配]
题意:
给一张无向图和一棵生成树,改变一些边的权值使生成树为最小生成树,代价为改变权值和的绝对值,求最小代价
线性规划的形式:
$Min\quad \sum\limits_{i=1}^{m} \delta_i$
$Sat\quad $非树边边权$\ge$生成树上路径任何一条边的边权
$i$非树边$j$树边
$w_i+\delta_i \ge w_j-\delta_j$
然后可以转化成二分图最小顶标和来求解
这里需要求二分图最大权非完美匹配,我的做法是遇到$d[t] < 0$就退出,反正这道题过了
然后很高兴的$1A$了就去看金刚狼3了好感动 现在补题解...
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=,M=2e5+,INF=1e9;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} int n,m,s,t,g[][],u,v,id[][],num;
struct data{int u,v,w;}a[M]; int q[N],p;
struct Graph{
struct edge{int v,ne;}e[M];
int cnt,h[N];
inline void ins(int u,int v){
cnt++;
e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
}
bool dfs(int u,int fa,int tar){
if(u==tar) return true;
for(int i=h[u];i;i=e[i].ne)
if(e[i].v!=fa){
q[++p]=id[u][e[i].v];
if(dfs(e[i].v,u,tar)) return true;
p--;
}
return false;
}
}G; struct Edge{
int v,ne,w,c,f;
Edge(){}
Edge(int v,int w,int c,int f):v(v),w(w),c(c),f(f){}
}e[M];
int cnt,h[N];
inline void ins(int u,int v,int w,int c){//printf("ins %d %d %d %d\n",u,v,w,c);
cnt++;
e[cnt]=Edge(v,w,c,);e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt]=Edge(u,-w,,);e[cnt].ne=h[v];h[v]=cnt;
} void build(){
s=;t=m+;
for(int i=;i<n;i++) ins(s,i,,);
for(int i=n;i<=m;i++) ins(i,t,,);
for(int i=n;i<=m;i++){
p=;
G.dfs(a[i].u,,a[i].v);
//printf("now %d\n",i);
//for(int j=1;j<=p;j++) printf("%d ",q[j]);puts("");
for(int j=;j<=p;j++) ins(q[j],i,a[q[j]].w-a[i].w,);
}
} int d[N],head,tail,inq[N],pre[N],pos[N];
inline void lop(int &x){if(x==N)x=;}
bool spfa(){
//memset(d,127,sizeof(d));
for(int i=s;i<=t;i++) d[i]=-INF,inq[i]=;
//memset(inq,0,sizeof(inq));
head=tail=;
d[s]=;inq[s]=;q[tail++]=s;
pre[t]=-;
while(head!=tail){
int u=q[head++];inq[u]=;lop(head);
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v,w=e[i].w;
if(d[v]<d[u]+w&&e[i].c>e[i].f){
d[v]=d[u]+w;
pre[v]=u;pos[v]=i;
if(!inq[v])q[tail++]=v,inq[v]=,lop(tail);
}
}
}
return pre[t]!=-;
}
int mcmf(){
int flow=,cost=;
while(spfa()){
int f=INF;
for(int i=t;i!=s;i=pre[i]) f=min(f,e[pos[i]].c-e[pos[i]].f);
flow+=f;
if(d[t]<) break;
cost+=d[t]*f;//printf("%d %d %d\n",f,d[t],cost);
for(int i=t;i!=s;i=pre[i]){
e[pos[i]].f+=f;
e[((pos[i]-)^)+].f-=f;
}
}
return cost;
} int main(){
freopen("in","r",stdin);
n=read();m=read();
for(int i=;i<=m;i++)
u=read(),v=read(),g[u][v]=g[v][u]=read();
for(int i=;i<n;i++)
u=read(),v=read(),id[u][v]=id[v][u]=++num,a[num]=(data){u,v,g[u][v]},G.ins(u,v);
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
if(g[i][j]&&!id[i][j]) id[i][j]=id[j][i]=++num,a[num]=(data){i,j,g[i][j]};
//printf("lo %d %d %d\n",i,j,num); build();
printf("%d\n",mcmf());
}
BZOJ 1937: [Shoi2004]Mst 最小生成树 [二分图最大权匹配]的更多相关文章
- [BZOJ 1937][Shoi2004]Mst 最小生成树
传送门 $ \color{red} {solution:} $ 对于每条树边\(i\),其边权只可能变小,对于非树边\(j\),其边权只可能变大,所以对于任意非树边覆盖的树边有 \(wi - di & ...
- [BZOJ1937][SHOI2004]Mst最小生成树(KM算法,最大费用流)
1937: [Shoi2004]Mst 最小生成树 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 802 Solved: 344[Submit][Sta ...
- 【BZOJ1937】[Shoi2004]Mst 最小生成树 KM算法(线性规划)
[BZOJ1937][Shoi2004]Mst 最小生成树 Description Input 第一行为N.M,其中 表示顶点的数目, 表示边的数目.顶点的编号为1.2.3.…….N-1.N.接下来的 ...
- POJ2195 Going Home[费用流|二分图最大权匹配]
Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 22088 Accepted: 11155 Desc ...
- Hdu2255 奔小康赚大钱(二分图最大权匹配KM算法)
奔小康赚大钱 Problem Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好 ...
- [ACM] HDU 2255 奔小康赚大钱 (二分图最大权匹配,KM算法)
奔小康赚大钱 Problem Description 传说在遥远的地方有一个很富裕的村落,有一天,村长决定进行制度改革:又一次分配房子. 这但是一件大事,关系到人民的住房问题啊. 村里共同拥有n间房间 ...
- POJ2195 Going Home (最小费最大流||二分图最大权匹配) 2017-02-12 12:14 131人阅读 评论(0) 收藏
Going Home Description On a grid map there are n little men and n houses. In each unit time, every l ...
- HDU2255 奔小康赚大钱 —— 二分图最大权匹配 KM算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) ...
- 二分图最大权匹配——KM算法
前言 这东西虽然我早就学过了,但是最近才发现我以前学的是假的,心中感慨万千(雾),故作此篇. 简介 带权二分图:每条边都有权值的二分图 最大权匹配:使所选边权和最大的匹配 KM算法,全称Kuhn-Mu ...
随机推荐
- Stars(树状数组)
http://acm.hdu.edu.cn/showproblem.php?pid=1541 Stars Time Limit: 2000/1000 MS (Java/Others) Memor ...
- [C#]使用控制台获取天气预报
本例子主要是使用由中央气象局网站(http://www.nmc.gov.cn)提供的JSON API,其实现思路如下: 1.访问获取省份(包含直辖市.自治区等,以下简称省份)的网址(http://ww ...
- Spark_总结一
Spark_总结一 1.Spark介绍 1.1什么是Spark? Apache Spark是一个开源的集群计算框架,使数据计算更快(高效运行,快速开发) 1.2Spa ...
- win10安装配置jdk的环境变量
换了个硬盘,用上了win10,发现win10安装好jdk之后,配置环境变量这个相对于win7和xp还是有那么一丢丢区别的,趁着夜色,随笔一记. 1.安装jdk之后,或者也可以用之前安装好的文件夹,先记 ...
- 给外行或者刚入门普及一下关于C#,.NET Framework(.NET框架),.Net,CLR,ASP,ASP.Net, VS,以及.NET Core的概念
一.概念 1. C# :C#是微软公司发布的一种面向对象的.运行于.NET Framework之上的高级程序设计语言. 2..NET Framework(.NET框架):.NET framework ...
- PostgreSQL 的 distinct on 的理解
摘录自:http://www.cnblogs.com/gaojian/archive/2012/09/05/2671381.html 对于 select distinct on , 可以利用下面的例子 ...
- Python解析JSON详解
JSON 函数 使用 JSON 函数需要导入 json 库:import json. 函数 描述 json.dumps 将 Python 对象编码成 JSON 字符串 json.loads 将已 ...
- ASP.NET导出word实例
ASP.NET导出word实例 最近遇到一个题目就是如何在asp.net中将数据导出到word中,由于数据是动态的,所以需要在后台拼出想要的的格式,翻遍了网页找出了一个比较满意的代码,感谢那位高手.代 ...
- idea 远程调试 tomcat web应用
最近在做的一个东西,测试环境和本地环境差距太大,本地能运行的代码,放到测试环境上到处报错,哪里哪里都连不上,所以决定把代码部署到远程服务器上调试,节省时间. 网上看了很多教程,大部分都是互相抄来抄去, ...
- F5负载均衡虚拟服务器配置FTP端口访问不了
F5配置ip映射到地址池ftp服务,访问报错:FTP出现"数据 Socket 错误: 连接被拒""ftp 列表错误"解决办法 1条回答 FTP的vs类型需要选择 ...