题意:这是bc round 71 div 1 的 1004 直接去看中文题意

分析:

首先,一种合法方案对应了原图的一棵生成树。

我们知道,最小生成树有一个性质是最大边最小。

因此,我们可以枚举生成树的最小边,去掉比该边小的边后对新图求最小生成树,那么我们所要的最优解一定包含在其中。

时间复杂度O(Mlog M+M^2*a (N),显然仅仅这个效率是不够的。

可以发现我们每次枚举后都重新求了最小生成树,事实上这是不必要的。

考虑从大到小枚举生成树的最小边,我们要做的实际上是每次加入一条边,维护当前图的最小生成树。

加入一条边时,我们需要判断这条边能否与之前的边构成环。

I 若能构成环,用该边替代环中最大边一定更优;

II 若不能构成环,直接加入该边即可。

找环中最大边可以用DFS 实现。若图中现有的边数为N-1N−1,我们就可以更新答案。

这样,事件复杂度就降到了O(M\log M+MN)O(MlogM+MN)。

更高的效率的方法,我们涉及的操作为加边、删边、查询路径最大边,因此可以使用LCT 来维护。

注:我按照题解写了一发,肯定是我手残,没有理解人家的意思,我发现我写出来还没题解上的效率不行的快

肯定我不行,

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=;
const int mod=1e9+;
const LL INF=INT_MAX;
int head[maxn],p;
struct Edge
{
LL u,v,next;
LL w,mark;
bool operator<(const Edge &e)const
{
return w<e.w;
}
} edge[],o[];
void add(int u,int v,int w)
{
edge[p].u=u;
edge[p].v=v;
edge[p].w=w;
edge[p].mark=;
edge[p].next=head[u];
head[u]=p++;
}
int fa[maxn];
int find(int x)
{
if(x==fa[x])return x;
return fa[x]=find(fa[x]);
}
LL tmp,vv,_max;
void dfs(int u,int f,int res)
{
if(u==vv)
tmp=res;
for(int i=head[u]; ~i; i=edge[i].next)
{
if(edge[i].v==f)continue;
if(edge[i].mark)continue;
_max=max(_max,edge[i].w);
int c=res;
if(res==-||edge[i].w>edge[c].w)c=i;
dfs(edge[i].v,u,c);
}
}
int main()
{
int T,n,m;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=; i<=m; ++i)
scanf("%I64d%I64d%I64d",&o[i].u,&o[i].v,&o[i].w);
sort(o+,o++m);
for(int i=; i<=n; ++i)fa[i]=i;
p=;
memset(head,-,sizeof(head));
int cnt=;
LL ans=INF;
for(int i=m; i>; --i)
{
tmp=-,_max=,vv=o[i].v;
if(cnt==n-)
{
dfs(o[i].u,,-);
ans=min(ans,_max-o[i+].w);
}
int fx=find(o[i].u);
int fy=find(o[i].v);
if(fx!=fy)
{
++cnt;
fa[fx]=fy;
}
else
{
if(tmp==-)
dfs(o[i].u,,-);
edge[tmp].mark=edge[tmp^].mark=;
}
add(o[i].u,o[i].v,o[i].w);
add(o[i].v,o[i].u,o[i].w);
}
if(cnt==n-)
{
_max=;
dfs(,,-);
ans=min(ans,_max-o[].w);
}
if(ans==INF)printf("-1\n");
else printf("%I64d\n",ans);
}
return ;
}

HDU 5624 KK's Reconstruction 最小生成树的更多相关文章

  1. HDU 5624 KK's Reconstruction

    这题目测是数据水了.我这种暴力写法显然是可以卡超时的. 假设有2000个点,15000条边,前面10000条不能构成树,后面5000条可以,这种数据显然可以卡超时. #include <stdi ...

  2. HDU 5723 Abandoned country 【最小生成树&&树上两点期望】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=5723 Abandoned country Time Limit: 8000/4000 MS (Java/ ...

  3. HDU 5723 Abandoned country (最小生成树 + dfs)

    Abandoned country 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5723 Description An abandoned coun ...

  4. HDU 5723 Abandoned country(最小生成树 + 树形DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5723 [题目大意] n座城市,m条路径,求解: 1.最短的路径和,使得n座城市之间直接或者间接连通 ...

  5. Hdu 1301 Jungle Roads (最小生成树)

    地址:http://acm.hdu.edu.cn/showproblem.php?pid=1301 很明显,这是一道“赤裸裸”的最小生成树的问题: 我这里采用了Kruskal算法,当然用Prim算法也 ...

  6. Qin Shi Huang's National Road System HDU - 4081(树形dp+最小生成树)

    Qin Shi Huang's National Road System HDU - 4081 感觉这道题和hdu4756很像... 求最小生成树里面删去一边E1 再加一边E2 求该边两顶点权值和除以 ...

  7. HDU 1162 Eddy's picture (最小生成树)(java版)

    Eddy's picture 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1162 ——每天在线,欢迎留言谈论. 题目大意: 给你N个点,求把这N个点 ...

  8. HDU 5723 Abandoned country(最小生成树+边两边点数)

    http://acm.split.hdu.edu.cn/showproblem.php?pid=5723 题意:给出一个无向图,每条路都有一个代价,求出把所有城市连通的最小代价.在此基础上,国王会从这 ...

  9. hdu 3371 Connect the Cities(最小生成树)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3371 984ms风险飘过~~~ /************************************ ...

随机推荐

  1. hive-site.xml 参数设置

    <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="confi ...

  2. iOS 网络编程

    iOS 开发中所需的数据基本都是来自网络,网络数据请求是 iOS 编程中必不可少的,应该熟练掌握网络请求. 网络请求方式有 :GET , POST , PUT ,DELETE 等,其中常用的就是 GE ...

  3. PAT-乙级-1033. 旧键盘打字(20)

    1033. 旧键盘打字(20) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 旧键盘上坏了几个键,于是在敲一段文 ...

  4. 谈谈js中for in 需要注意的地方

    js中for in 可以遍历对象或数组的显性属性,也就是说我们自己定义的属性是可以遍历的,那些原型上默认已有的属性,例如:Object.prototype.toString.Object.protot ...

  5. 20130729--Samba的学习

    (一).基本概念 samba是一个能让你的Unix计算机和其它MS Windows计算机相互共享资源的软件. samba提供有关资源共享的三个功能,包括:smbd,执行它可以使Unix能够共享资源给其 ...

  6. fiddler 插件开发二

    本篇主要讲解Fildder插件开发中的涉及到的主要接口与类. 1.IFiddlerExtension 接口 如果要开发的自定义插件有UI界面,则需要实现IFiddlerExtension 接口.你程序 ...

  7. 找出程序cpu使用率高的原因

    确定是CPU过高 使用top观察是否存在CPU使用率过高现象 找出线程 对CPU使用率过高的进程的所有线程进行排序 ps H -e -o pid,tid,pcpu,cmd --sort=pcpu |g ...

  8. 好看的游戏soul calibur

    http://soulcalibur.fr/index.php?wiki/sophitia/ http://astuce-soluce.playfrance.com/index.php/Soul_Ca ...

  9. 220. Contains Duplicate III

    题目: Given an array of integers, find out whether there are two distinct indices i and j in the array ...

  10. 同步or异步

    一.什么是同步?什么是异步? 同步:如果有多个任务要执行,这些任务必须逐个执行,一个任务的执行会导致整个流程的暂时等待,这些任务没有办法并发地执行: 异步:如果有多个任务要执行,这些任务可以并发执行, ...