题目链接

题意,判断次小生成树与最小生成树的权值和是否相等。

豆丁文档—— A-star和第k短路和次小生成树和Yen和MPS寻路算法

法一:

先求一次最小生成树,将这棵树上的边加入一个向量中,再判断去掉前面所求的最小生成树的某条边能否再求得一棵等权值的最小生成树

复杂度O(NElogE)

//稠密图不可用

#include<bits/stdc++.h>
using namespace std; 

 + ;
 + ;
int fa[maxn];
int n, m;
vector<int> TreeEdge;

struct Road            //保存每条路的信息
{
    int u,v,w;
    bool operator<(const Road& t) const      //按长度由小到大排序
    {
        return w<t.w;
    }
} R[maxm];
//初始化并查集
void Init()
{
    ; i <= n; i++)
        fa[i]=i; //每个点自成一个连通分量
}
//找x的祖先
int Find(int x)
{
    return x == fa[x]? x:fa[x]=Find(fa[x]);
}
//判断图的连通性
bool isAccess()
{
    );
    ; i <= n; i++)
        if(f!=Find(i)) return false;
    return true;
}
//kruskal求不要k这条边的最小生成树
int kruskal(int k)
{
    ;
    Init();
    ; i<m; i++)
    {
        if(i!=k)
        {
            int tx=Find(R[i].u);
            int ty=Find(R[i].v);
            if(tx!=ty)
            {
                ans+=R[i].w;
                fa[tx]=ty;
            }
        }
    }
    if(isAccess()) return ans;    //如果是生成树,返回权值
    ;
}

int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        TreeEdge.clear();
        scanf("%d%d",&n,&m);
        ; i<m; i++)
            scanf("%d%d%d",&R[i].u,&R[i].v,&R[i].w);
        sort(R, R+m);                //将所有边排序
        Init();
        //===begin===MST
        ;                //求最小生成树
        ; i<m; i++)
        {
            int tx=Find(R[i].u), ty=Find(R[i].v);
            if(tx!=ty)
            {
                ans+=R[i].w;
                fa[tx]=ty;
                TreeEdge.push_back(i);//将这条边加入生成树中
            }
        }
        //===end===MST
        ;
        ;i<TreeEdge.size();i++)
            if(kruskal(TreeEdge[i])==ans)    //看看不用这条边能否再次生成一棵最小生成树
            {
                ok=;
                break;
            }
        if(ok) printf("Yes\n");
        else printf("No\n");
    }
}

法二:

首先求出原图的最小生成树,记录权值之和为Minst.枚举添加每条不在最小生成树上的边<u,v>,加上以后一定会形成一个环,找到环上权值第二大的边(即除<u,v>外最大的边)把它删除掉,计算当前生成树的权值之和。取所有枚举修改的生成树权值之和的最小值,就是次小生成树。具体实现时,更简单的方法是从每个节点i遍历整个最小生成树,定义F[i,j]为从i到j的路径上最大边的权值。遍历图求出F[i,j]的值,然后对于添加每条不在最小生成树中的边<i,j>,新的生成树权值之和就是Minst+w<i,j>-F[j],记录其最小值,则为次小生成树。该算法的时间复杂度为O(n^2+m)。由于只用求一次最小生成树,可以用最简单的Prim算法,时间复杂度为O(n^2)。算法的瓶颈不在于最小生成树,而在于O(n^2+m)的枚举加边修改,所以用更好的最小生成树算法是没有必要的。(详见豆丁文档)

复杂度O(n^2)

标程如下:

#include<bits/stdc++.h>
using namespace std;
#define maxN 510
#define MAX 0x0fffffff
#define MIN -0x0fffffff

int N,M,map[maxN][maxN],dis[maxN],maxlen[maxN][maxN],pre[maxN];
bool vis[maxN];

int prim()
{
    int i,j,k,minn,pr;
    memset(vis,false,sizeof(vis));
    ; i<=N; i++)
        dis[i]=map[][i],pre[i]=;
    vis[]=true;
    ; j<N; j++)
    {
        minn=MAX;
        ; i<=N; i++)
            if(!vis[i]&&dis[i]<minn)
                k=i,minn=dis[i];
        pr=pre[k];
        maxlen[k][pr]=maxlen[pr][k]=map[k][pr];
        ; i<=N; i++)
            if(vis[i])
                maxlen[i][k]=maxlen[k][i]=max(maxlen[i][pr],maxlen[k][pr]);
        vis[k]=true;
        ; i<=N; i++)
            if(!vis[i]&&dis[i]>map[i][k])
            {
                dis[i]=map[i][k];
                pre[i]=k;
            }
    }
    ; i<N; i++)
        ; j<=N; j++)
            if(pre[i]==j||pre[j]==i)continue;
            ;
    ;
}
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        int u,v,w;
        scanf("%d%d",&N,&M);
        ; i<=N; i++)
            ; j<=N; j++)
            {
                map[i][j]=MAX;
                maxlen[i][j]=MIN;
            }
        ; i<M; i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            map[u][v]=map[v][u]=w;
        }
        if(prim())printf("Yes\n");
        else printf("No\n");
    }
}

nyoj_118:修路方案(次小生成树)的更多相关文章

  1. Nyoj 修路方案(次小生成树)

    描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路. 现在已经知道哪些城市之间可以修路,如果修路,花费是多少. 现在,军师小工已经找到 ...

  2. hdu4081 秦始皇修路(次小生成树)

    题目ID:hdu4081   秦始皇修路 题目链接:点击打开链接 题目大意:给你若干个坐标,每个坐标表示一个城市,每个城市有若干个人,现在要修路,即建一个生成树,然后有一个魔法师可以免费造路(不消耗人 ...

  3. 修路方案 Kruskal 之 次小生成树

    次小生成树 : Kruskal 是先求出来  最小生成树 , 并且记录下来所用到的的边 , 然后再求每次都 去掉最小生成树中的一个边 , 这样求最小生成树 , 然后看能不能得到 和原来最小生成树一样的 ...

  4. nyoj--118--修路方案(次小生成树)

    修路方案 时间限制:3000 ms  |  内存限制:65535 KB 难度:5 描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路. ...

  5. 修路方案(nyoj)

    算法:次小生成树 描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路. 现在已经知道哪些城市之间可以修路,如果修路,花费是多少. 现在 ...

  6. NYOJ 118 修路方案

    修路方案 时间限制:3000 ms  |  内存限制:65535 KB 难度:5   描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修 ...

  7. hdu4081 次小生成树变形

    pid=4081">http://acm.hdu.edu.cn/showproblem.php?pid=4081 Problem Description During the Warr ...

  8. HDU 4081 Qin Shi Huang's National Road System 次小生成树变种

    Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/3 ...

  9. 【次小生成树】bzoj1977 [BeiJing2010组队]次小生成树 Tree

    Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了.小 P 说,让小 C 求出一 ...

随机推荐

  1. Node.js爬虫-爬取慕课网课程信息

    第一次学习Node.js爬虫,所以这时一个简单的爬虫,Node.js的好处就是可以并发的执行 这个爬虫主要就是获取慕课网的课程信息,并把获得的信息存储到一个文件中,其中要用到cheerio库,它可以让 ...

  2. cas单点登录系统:客户端(client)详细配置

    最近一直在研究cas登录中心这一块的应用,分享一下记录的一些笔记和心得.后面会把cas-server端的配置和重构,另外还有这几天再搞nginx+cas的https反向代理配置,以及cas的证书相关的 ...

  3. Windows server 2008 r2 开启Aero

    1.右键“计算机”----“管理”----“添加功能”,选上“桌面体验”,一般来说要把服务器系统做成工作 站的话,最好再选上“优质WINDOWS音频视频体验”,如果有无线网卡再选上“无线LAN服务”, ...

  4. Mac 上所有的命令行相关问题的总结

    1. java 系列命令 jdk,jar,war等等文件的执行方式 2. brew 系列命令 安装各种其他程序的命令例如:jenkins,MySQL,openssl brew list   列出所有的 ...

  5. JQuery与js具体使用的区别(不全,初学)

    jQuery能大大简化Javascript程序的编写 要使用jQuery,首先要在HTML代码最前面加上对jQuery库的引用,比如: <script language="javasc ...

  6. 依赖注入之Autofac使用总结

    依赖倒置?控制反转(IOC)? 依赖注入(DI)? 你是否还在被这些名词所困扰,是否看了大量理论文章后还是一知半解了? 今天我想结合实际项目,和正在迷惑中的新手朋友一起来学习和总结依赖注入Autofa ...

  7. vue+websocket+express+mongodb实战项目(实时聊天)(二)

    原项目地址:[ vue+websocket+express+mongodb实战项目(实时聊天)(一)][http://blog.csdn.net/blueblueskyhua/article/deta ...

  8. 标准IO和重定向

    1.标准输入/输出/错误 当shell启动,它继承三个文件:stdin.stdout.stderr,标准输入通常来自键盘,标准输出和标准错误通常是屏幕.标准输入/输出/错误的文件描述符为0.1.2 2 ...

  9. noip模拟 市长选举

    题目描述 利贝尔王国的卢安市因为前段时间的市长被捕事件,导致没有市长管理城市.他们需要一个新的市长. 竞选的人有两位.一位是诺曼,因支持旅游业而受到支持者的拥护.一位是波尔多斯,代表的是卢安的传统行业 ...

  10. js中的事件,内置对象,正则表达式

    [JS中的事件分类] 1.鼠标事件: click/dbclick/mouseover/mouseout/mousemove/mousedown/mouseup 2.键盘事件: keydown: 键盘按 ...