解为基环树森林

证明其具有拟阵的性质:

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. Windows命令行下如何使用批处理异步打开一个浏览器进程

    Browse.bat @echo off if '%1'=='-c' ( start /d "C:\Program Files\Google\Chrome\Application\" ...

  2. 批处理-For详解

    大纲 一 前言 二 for语句的基本用法 三 for /f (delims.tokens.skip.eol.userbackq.变量延迟) 四 for /r (递归遍历) 五 for /d (遍历目录 ...

  3. Linux 文件系统概览

    本文导航 -定义07% -文件系统的基本功能12% -目录结构26% -Linux 统一目录结构50% -文件系统类型74% -挂载81% -结论90% -下个月92%   本文旨在高屋建瓴地来讨论 ...

  4. error eslint@5.12.0: The engine "node" is incompatible with this module.

    初始化 react项目时报错: error eslint@5.12.0: The engine "node" is incompatible with this module. E ...

  5. python之打印日志logging

    import logging # 简单打印日志举例 logging.basicConfig(level=logging.DEBUG) # 设置日志级别,WARN logging.warning('Wa ...

  6. codeforces518B

    Tanya and Postcard CodeForces - 518B 有个小女孩决定给他的爸爸寄明信片.她已经想好了一句话(即长度为n的字符串s),包括大写和小写英文字母.但是他不会写字,所以她决 ...

  7. Nginx PREACCESS阶段 如何限制每个客户端的并发连接数

    L:55 nginx.conf配置文件列子 limit_conn_zone $binary_remote_addr zone=addr:10m; #这里根据用户IP地址作为key做限制 并且名称为ad ...

  8. c++ 为自定义类添加stl遍历器风格的遍历方式

    为仿照stl的遍历风格,实现对自定义类型的遍历. 1. 需要遍历的基础结构: struct ConnectionPtr { int id_; int port_; string addr_; //st ...

  9. Markdown 文件转化为work文档

    1. 电脑安装pandoc 链接:https://pan.baidu.com/s/12H5wLO0JWph5TjrbeJI6mg 密码:ssgs 下载安装包解压即可用.记得配置系统环境变量 2.命令行 ...

  10. BZOJ2662[BeiJing wc2012]冻结——分层图最短路

    题目描述 “我要成为魔法少女!”     “那么,以灵魂为代价,你希望得到什么?” “我要将有关魔法和奇迹的一切,封印于卡片之中„„”     在这个愿望被实现以后的世界里,人们享受着魔法卡片(Spe ...