解为基环树森林

证明其具有拟阵的性质:

1、空集独立

2、基环树森林的子集仍然是基环树森林,满足遗传特性

3、对于基环树森林A,B,若|A|<|B| (边数),一定可以找到一条边e∈B,∉A,使A∪e仍然是基环树森林,满足扩充特性

扩充特性证明:

枚举A中的联通块

1、若A中这个联通块的边数<B中对应联通块的边数,显然存在一条满足要求的边

2、否则B中存在一条边连接了A的两个联通块。枚举B中这样的边,若这两个联通块至少有一个不是基环树,则该边满足要求。

否则,A中这两个联通块都是基环树,B中不是基环树,因此B中这个联通块的边数<A中这两个联通块的边数和。所以还存在其他的联通块之间的边满足要求

所以本题解法:

按边权从大到小排序,先构造出一颗最大权值基环树

然后按边权从大到小枚举之前没有用过的边u--v

首先明确不会存在原来联通块是树,加上这条边变成基环树的情况

因为之前已经构造了最大权值基环树

1、若u和v在同一个联通块,该联通块一定是基环树,那么新加的这条边可以替换环上的任意一条边,也可以替换u和v到环的路径上的一条边

2、若u和v不在同一个联通块,那么这两个联通块都是基环树,这条边可以替换两个环上的任意一条边,也可以替换u和v到环的路径上的一条边

无论哪种情况,都是用当前边去替换最大权值基环树上的边

遇上已经被替换过一次的边则停止替换,因为之前用的边的边权不会比现在的边的边权小

#include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; typedef long long LL; #define N 200001 struct node
{
int u,v,w;
int id;
bool use;
}e[N]; LL ans[N]; int fa[N],siz_p[N],siz_e[N];
int circle[N];//基环的环在哪儿 struct graph
{
int from,to,id,w;
int nxt;
}g[N<<];
int tot,front[N];
int pre[N]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} bool cmp(node p,node q)
{
return p.w>q.w;
} int find(int i) { return fa[i]==i ? i : fa[i]=find(fa[i]); } void unionn(int u,int v)
{
int fu=find(u),fv=find(v);
if(fu==fv)
{
circle[fu]=u;
siz_e[fu]++;
return;
}
fa[fu]=fv;
siz_e[fv]+=siz_e[fu]+;
siz_p[fv]+=siz_p[fu];
circle[fv]|=circle[fu];
} void add(int u,int v,int t)
{
g[++tot].from=u; g[tot].to=v; g[tot].id=e[t].id; g[tot].w=e[t].w; g[tot].nxt=front[u]; front[u]=tot;
g[++tot].from=v; g[tot].to=u; g[tot].id=e[t].id; g[tot].w=e[t].w; g[tot].nxt=front[v]; front[v]=tot;
} int dfs(int now,int last)
{
int tmp=,t;
for(int i=front[now];i;i=g[i].nxt)
{
t=g[i].to;
if(t==last) continue;
if(pre[t]==-) tmp=i;
if(pre[t]) continue;
pre[t]=i;
tmp|=dfs(t,now);
}
return tmp;
} void concat(int x,int w)
{
int now;
while()
{
now=pre[x];
if(ans[g[now].id]) break;
ans[g[now].id]=ans[]-g[now].w+w;
x=g[now].from;
}
} void out(LL x)
{
if(x>) out(x/);
putchar(x%+'');
} int main()
{
freopen("journey.in","r",stdin);
freopen("journey.out","w",stdout);
int n,m;
read(n); read(m);
for(int i=;i<=m;++i)
{
read(e[i].u); read(e[i].v); read(e[i].w);
e[i].id=i;
}
sort(e+,e+m+,cmp);
for(int i=;i<=n;++i)
{
fa[i]=i;
siz_p[i]=;
}
int fu,fv;
for(int i=;i<=m;++i)
{
fu=find(e[i].u);
fv=find(e[i].v);
if(siz_p[fu]==siz_e[fu] && siz_p[fv]==siz_e[fv]) continue;
ans[]+=e[i].w;
e[i].use=true;
unionn(e[i].u,e[i].v);
add(e[i].u,e[i].v,i); }
int u;
for(int i=;i<=n;++i)
{
u=find(i);
if(circle[u]) u=circle[u];
if(!pre[u])
{
pre[u]=-;
pre[u]=dfs(u,-);
}
}
for(int i=;i<=m;++i)
{
if(e[i].use) continue;
ans[e[i].id]=ans[];
concat(e[i].u,e[i].w);
concat(e[i].v,e[i].w);
}
for(int i=;i<=m;++i)
if(!ans[e[i].id]) ans[e[i].id]=ans[]-e[i].w;
for(int i=;i<=m;++i) out(ans[i]),putchar('\n');
}

cdqz2017-test11-奇诺之旅(拟阵)的更多相关文章

  1. bzoj 3105: [cqoi2013]新Nim游戏 异或高消 && 拟阵

    3105: [cqoi2013]新Nim游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 535  Solved: 317[Submit][Stat ...

  2. BZOJ3105 新Nim游戏 【拟阵】

    题目分析: 我不知道啥是拟阵啊,但有大佬说线性基相关的都是拟阵,所以直接贪心做了. 题目代码: #include<bits/stdc++.h> using namespace std; ; ...

  3. 【learning】加权拟阵与贪心

    首先.. 这篇东西的话算是一个关于拟阵部分知识的小总结,有些语言相对来说偏向便于理解方面,所以可能..有一些说法会不是那么严谨大概是这样 ​ 一些概念 线性无关:一组数据中没有一个量可以写成其余量的线 ...

  4. bzoj 4004 [JLOI2015]装备购买 拟阵+线性基

    [JLOI2015]装备购买 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1820  Solved: 547[Submit][Status][Dis ...

  5. 组合优化学习笔记<之>从贪心算法到子集系统再到拟阵

    贪心算法是用的比较多的一种优化算法,因为它过程简洁优美,而且结果有效.有些优化问题如最大权森林(MWF)是可以用贪心问题求解的,由于最小支撑树(MST)问题与MWF是等价的,所以MST也是可以用贪心算 ...

  6. 【BZOJ2460】元素(拟阵)

    题意:给定n个物品,每个物品有属性x和价值y,要求从中选出一些使得价值和最大并且其中没有属性xor和为0的非空子集 n<=1000,x<=1e18,y<=1e4 思路:没有xor和为 ...

  7. bzoj 4004 [JLOI2015]装备购买——拟阵证明贪心+线性基

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4004 看Zinn博客水过去…… 运用拟阵可以证明按价格从小到大买的贪心是正确的.但自己还不会 ...

  8. 从拟阵基础到 Shannon 开关游戏

    从拟阵基础到 Shannon 开关游戏 本文中的定理名称翻译都有可能不准确!如果有找到错误的同学一定要联系我! 本文长期征集比较好的例题,如果有比较典型的题可以联系我 目录 从拟阵基础到 Shanno ...

  9. bzoj 4004: [JLOI2015]装备购买 拟阵 && 高消

    4004: [JLOI2015]装备购买 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 337  Solved: 139[Submit][Status ...

随机推荐

  1. 用IntelliJ IDEA编译,编译之后提示 无效的标记: -release

    软件版本:ideaIU-2016.3.2 JDK:jdk-9.0.4_windows-x64_bin 开始的时候建立一个maven项目,发现编译的时候提示[无效的标记: -release],以为是项目 ...

  2. lumen或者laravel安装指定版本

    方法一 安装器安装:缺点不能安装指定版本 composer global require "laravel/lumen-installer" lumen new blog comp ...

  3. 使用docker-compose 大杀器来部署服务

    使用docker-compose 大杀器来部署服务 上 我们都听过或者用过 docker,然而使用方式却是仅仅用手动的方式,这样去操作 docker 还是很原始. 好吧,可能在小白的眼中噼里啪啦的对着 ...

  4. 命令行方式(SSH or powershell )远程windows server

    1. 使用ssh的方式远程登录window server 网上找到的方法大部分是freesshd 或者是Copsshd这样的工具 方式就是 下载安装文件,然后服务器端进行安装: 安装完成之后作为服务启 ...

  5. modern effective C++ -- Deducint Types

    1. 理解模板类型推导 1. expr是T& template<typename T> void f(T & param); // 我们声明如下变量 int x = 27; ...

  6. 使用嵌入式jetty实现文件服务器

    pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...

  7. BZOJ4502串——AC自动机(fail树)

    题目描述 兔子们在玩字符串的游戏.首先,它们拿出了一个字符串集合S,然后它们定义一个字 符串为“好”的,当且仅当它可以被分成非空的两段,其中每一段都是字符串集合S中某个字符串的前缀. 比如对于字符串集 ...

  8. Hibernate 查询技术

    转载: http://blog.csdn.net/u014078192/article/details/24986475 一.Hibernate的三种查询方式(掌握) Hibernate中提供了三种查 ...

  9. MVC 多语言

    最近项目需要用到多语言. 研究了一下,也参考了很多技术文章. 这里贴一下参考地址:http://www.cnblogs.com/unintersky/p/3969612.html 主要步骤我这里简述一 ...

  10. bzoj1001狼抓兔子

    1001: [BeiJing2006]狼抓兔子 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你 ...