分析:第一问还是很好做的,关键是怎么做第二问.我们可以每次删掉最小生成树上的一条边,然后再求一次最小生成树,看边权和大小和原来的是不是一样的,不过这个做法效率很低.

考虑Kruskal算法的原理,每次加边权最小的边,如果边上的两个点不连通.如果在最小生成树的基础上把不是上面的边给加上去,就会形成环,在环上找除了这条边之外的最大边权,如果等于新加入的这条边,那么就有多个最小生成树.为什么这样呢?我们把最大边拿掉,添加进这条边,两个点还是连通的,边权和一定,只是在Kruskal的时候先考虑了那条最大边而已.

接下来只需要求出若干对点路径上的最大边权就可以了,我们可以用倍增算法来求.

写这道题的时候把w数组写成了e[i].w,挂惨了......以后要对同名数组多留意.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const int maxn = ; int T, n, m, head[maxn], nextt[maxn], to[maxn], w[maxn], tot = ,fa[maxn],d[maxn],f[maxn][],dmax[maxn][];
long long ans;
bool flag = false; struct node
{
int u, v, w,use;
}e[maxn]; void add(int x, int y, int z)
{
w[tot] = z;
to[tot] = y;
nextt[tot] = head[x];
head[x] = tot++;
} bool cmp(node a, node b)
{
return a.w < b.w;
} int find(int x)
{
if (x == fa[x])
return x;
return fa[x] = find(fa[x]);
} void dfs(int u, int depth,int from)
{
d[u] = depth;
f[u][] = from;
for (int i = head[u]; i; i = nextt[i])
{
int v = to[i];
if (v != from)
{
dmax[v][] = w[i];
dfs(v, depth + , u);
}
}
} int LCA(int x, int y)
{
if (x == y)
return ;
if (d[x] < d[y])
swap(x, y);
int maxx = ;
for (int i = ; i >= ; i--)
if (d[f[x][i]] >= d[y])
{
maxx = max(maxx, dmax[x][i]);
x = f[x][i];
} if (x == y)
return maxx; for (int i = ; i >= ; i--)
if (f[x][i] != f[y][i])
{
maxx = max(maxx, max(dmax[x][i], dmax[y][i]));
x = f[x][i];
y = f[y][i];
}
maxx = max(maxx, max(dmax[x][], dmax[y][]));
return maxx;
} int main()
{
scanf("%d", &T);
while (T--)
{
memset(head, , sizeof(head));
tot = ;
ans = ;
flag = false;
scanf("%d%d", &n, &m);
memset(d, , sizeof(d));
memset(f, , sizeof(f));
memset(dmax, , sizeof(dmax));
for (int i = ; i <= n; i++)
fa[i] = i;
for (int i = ; i <= m; i++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
e[i].u = a;
e[i].v = b;
e[i].w = c;
e[i].use = ;
}
sort(e + , e + + m, cmp);
for (int i = ; i <= m; i++)
{
int fx = find(e[i].u), fy = find(e[i].v);
if (fx != fy)
{
add(e[i].u, e[i].v, e[i].w);
add(e[i].v, e[i].u, e[i].w);
fa[fx] = fy;
ans += e[i].w;
e[i].use = ;
}
}
printf("%lld\n", ans);
dfs(, ,);
for (int j = ; j <= ; j++)
for (int i = ; i <= n; i++)
{
f[i][j] = f[f[i][j - ]][j - ];
dmax[i][j] = max(dmax[i][j - ], dmax[f[i][j - ]][j - ]);
}
for (int i = ; i <= m; i++)
if (!e[i].use && LCA(e[i].u, e[i].v) == e[i].w)
{
flag = ;
break;
}
if (flag)
puts("No");
else
puts("Yes");
} return ;
}

常州模拟赛d7t3 水管的更多相关文章

  1. 常州模拟赛d4t1 立方体

    题目描述 立方体有 6 个面,每个面上有一只奶牛,每只奶牛都有一些干草.为了训练奶牛的合作精神,它 们在玩一个游戏,每轮:所有奶牛将自己的干草分成 4 等份,分给相邻的 4 个面上的奶牛. 游戏开始, ...

  2. 常州模拟赛d6t3 噪音

    FJ有M个牛棚,编号1至M,刚开始所有牛棚都是空的.FJ有N头牛,编号1至N,这N头牛按照编号从小到大依次排队走进牛棚,每一天只有一头奶牛走进牛棚.第i头奶牛选择走进第p[i]个牛棚.由于奶牛是群体动 ...

  3. bzoj3743 [Coci2015]Kamp 常州模拟赛d6t2

    3743: [Coci2015]Kamp Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 484  Solved: 229[Submit][Status ...

  4. 常州模拟赛d5t2 mogician

    分析:一个暴力的思想是枚举g,然后枚举每个数ai,看能不能符合要求,这样复杂度是O(nA)的,直接T掉了.也没什么其他的办法了,在暴力的基础上优化一下,优化的关键是要如何快速统计出不满足要求的数的个数 ...

  5. 常州模拟赛d5t1 journalist

    分析:出题人丧心病狂卡spfa......只能用dijkstar+堆优化. 主要的难点是字典序的处理上,一个想法是在做最短路的时候处理,边松弛边记录,比个大小记录最佳答案.具体的思路大概和最短路计数差 ...

  6. 常州模拟赛d4t3 字符串划分

    题目描述 给你一串由小写字母组成的字符串,希望你把它划分成一些小段,使得每一小段字符串中的字母 都不相同,并且希望分的段数尽量少. 然后,把这些小段按字典序排序后输出,中间由一个空格分隔. 例如:字符 ...

  7. 常州模拟赛d4t2 陶陶摘苹果

    题目描述 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出 n 个苹果.苹果成熟的时候,陶陶就会 跑去摘苹果. 陶陶的手不能弯 (他仅能把手伸直),当且仅当陶陶达到的高度与苹果的高度相等的时候,陶陶 ...

  8. 常州模拟赛d3t3 两只怪物心心相印

    题目背景 从前我是一位无名的旅人,旅途中我得到了某样东西:贤者之石.我因此得到悠久的时光和漂泊的生命.1897年冬天,我一时兴起舍弃了旅人的生活. 贤者之石创造出来的,是货真价实的黄金.我的名声传遍了 ...

  9. 常州模拟赛d3t2 灰狼呼唤着同胞

    题目背景 我的母亲柯蒂丽亚,是一个舞者.身披罗纱,一身异国装扮的她,来自灰狼的村子. 曾经在灰狼村子担任女侍的她,被认定在某晚犯下可怕的罪行之后,被赶出了村子. 一切的元凶,都要回到母亲犯下重罪的那一 ...

随机推荐

  1. hello word!------为什么开通博客以及自我介绍

    来北京已经一年半的日子了,已经完全成功熟练的成为了另一个我,没有了半年前刚来时的那种焦虑.急躁和格格不入. 回想起来那段时间,大概是我人生中非常重要的时期了,去年那个夏天,只身一人背上行囊踏上了北上的 ...

  2. lintcode671 循环单词

    循环单词   The words are same rotate words if rotate the word to the right by loop, and get another. Cou ...

  3. CSP201709-1:打酱油

    引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...

  4. Spark mlib的本地向量

    Spark mlib的本地向量有两种: DenseVctor :稠密向量 其创建方式 Vector.dense(数据) SparseVector :稀疏向量 其创建方式有两种: 方法一:Vector. ...

  5. [Clr via C#读书笔记]Cp13接口

    Cp13接口 类和接口继承 接口只提供签名,不提供实现:等效于契约:凡事能使用具名接口的地方都能够使用实现了的接口. 定义接口 定义很简单,FCL也提供了大量的现成接口供使用: 继承接口 类不能多继承 ...

  6. Linux系统负载查询

    查询Linux系统负载情况,一般需要了解三个方面的信息: 1.Linux系统配置.如Linux版本号.CPU.内存.网络.磁盘等: 2.收集系统负载信息的手段.常用的工具包有sysstat和procp ...

  7. Python 学习笔记之——用 sklearn 对数据进行预处理

    1. 标准化 标准化是为了让数据服从一个零均值和单位方差的标准正态分布.也即针对一个均值为 \(mean\) 标准差为 \(std\) 的向量 \(X\) 中的每个值 \(x\),有 \(x_{sca ...

  8. 2.安装hdfs yarn

    下载hadoop压缩包设置hadoop环境变量设置hdfs环境变量设置yarn环境变量设置mapreduce环境变量修改hadoop配置设置core-site.xml设置hdfs-site.xml设置 ...

  9. LintCode-105.复制带随机指针的链表

    复制带随机指针的链表 给出一个链表,每个节点包含一个额外增加的随机指针可以指向链表中的任何节点或空的节点. 返回一个深拷贝的链表. 挑战 可否使用O(1)的空间 标签 哈希表 链表 优步 code / ...

  10. matlab的二维卷积操作(转)

    MATLAB的conv2函数实现步骤(conv2(A,B)): 其中,矩阵A和B的尺寸分别为ma*na即mb*nb ① 对矩阵A补零,第一行之前和最后一行之后都补mb-1行,第一列之前和最后一列之后都 ...