博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
图论板子 次小生成树
阅读量:4493 次
发布时间:2019-06-08

本文共 2670 字,大约阅读时间需要 8 分钟。

由最小生成树T进行一次可行交换得到的新的生成树的集合 称为T的邻集 N(T)

(即 最小生成树的某两节点间有重边 可替换 或 原图中存在其它边可重新连接这些节点)
找到可替换边中权值最小的那条 替换即可
实现:存最小生成树上每两点间最大距离,
遍历每条不在最小生成树上的边,更新 以这条边 替换 该边两端节点间的最大距离 后的最小值

在kruskal算法基础上实现

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;const int INF=0x3f3f3f3f;typedef pair
pr;typedef long long ll;#define fi first#define se second#define me(x) memset(x, -1, sizeof(x))#define mem(x) memset(x, 0, sizeof(x))#define N 10000+5struct node{ int u, v, w; bool vis;}e[4*N];bool cmp(node a, node b){ if(a.w==b.w && a.u==b.u) return a.v
g[1005];int fin(int x){ int r=x; while(r!=p[r]) r=p[r]; int i=x, t; while(p[i]!=r) { t=p[i]; p[i]=r; i=t; } return r;}void kruskal(){ sort(e, e+m, cmp); int i, j, l; for(i=0; i<=n; i++) p[i]=i, g[i].clear(), g[i].push_back(i); int k=0, sum=0, maxn[105][105]; for(i=0; i
>t; while(t--) { cin>>n>>m; for(i=0; i
>e[i].u>>e[i].v>>e[i].w, e[i].vis=false; kruskal(); }}

 

#include<cstdio>#include<cstdlib>#include<iostream>#include<algorithm>#include<cstring>#include<cmath>#include<queue>#include<set>#include<string>using namespace std;const int INF=0x3f3f3f3f;typedef pair<int, int> pr;typedef long long ll;#define fi first#define se second#define me(x) memset(x, -1, sizeof(x))#define mem(x) memset(x, 0, sizeof(x))#define N 10000+5struct node{    int u, v, w;    bool vis;}e[4*N];

bool cmp(node a, node b){    if(a.w==b.w && a.u==b.u) return a.v<b.v;    if(a.w==b.w) return a.u<b.u;    return a.w<b.w;}int n, m;int p[N];vector<int> g[1005];
int fin(int x){    int r=x;    while(r!=p[r])        r=p[r];    int i=x, t;    while(p[i]!=r)    {        t=p[i];        p[i]=r;        i=t;    }    return r;}void kruskal(){    sort(e, e+m, cmp);    int i, j, l;    for(i=0; i<=n; i++)        p[i]=i, g[i].clear(), g[i].push_back(i);    int k=0, sum=0, maxn[105][105];
    for(i=0; i<m; i++)    {        if(k==n-1) break;        int x=fin(e[i].u), y=fin(e[i].v);        if(x!=y)        {
            k++;            p[y]=x;            e[i].vis=true;            sum+=e[i].w;            int lenx=g[x].size(), leny=g[y].size();            for(j=0; j<lenx; j++)                for(l=0; l<leny; l++)                    maxn[g[x][j]][g[y][l]]=maxn[g[y][l]][g[x][j]]=e[i].w;                    //更新两点间最大值(kruskal保证边权递增            int tmp[1005];            for(j=0; j<lenx; j++)                tmp[j]=g[x][j];            for(l=0; l<leny; l++)                g[x].push_back(g[y][l]);//加点            for(j=0; j<lenx; j++)                g[y].push_back(tmp[j]);//加点        }    }    int sum1=INF;    for(i=0; i<m; i++)        if(!e[i].vis) sum1=min(sum1, sum+e[i].w-maxn[e[i].u][e[i].v]);        //更新替换后的最小值    //cout<<sum<<endl<<sum1<<endl;    if(sum<sum1) cout<<sum<<endl;    else cout<<"Not Unique!"<<endl;}
int main(){    int i, j, k, t;    cin>>t;    while(t--)    {        cin>>n>>m;        for(i=0; i<m; i++)            cin>>e[i].u>>e[i].v>>e[i].w, e[i].vis=false;        kruskal();    }}

 

转载于:https://www.cnblogs.com/op-z/p/11281912.html

你可能感兴趣的文章
2018年上半年自考 郑州大学 软件工程(080720)
查看>>
shell编程
查看>>
[转载]Oracle Golden Gate - 概念和机制 (ogg)
查看>>
「模板」AC自动机(ACAM)
查看>>
[原创]我的WCF之旅(4):WCF中的序列化(Serialization)- Part I - Artech - 博客园
查看>>
4-8
查看>>
测试用例设计白皮书--测试用例设计综合策略
查看>>
iView 实战系列教程(21课时)_4.iView 实战教程之布局篇(二)
查看>>
20150501 调试分析之 修改内核来定位系统僵死问题
查看>>
【7集iCore3基础视频】7-3 iCore3硬件介绍
查看>>
数据库基础
查看>>
C 标准库 - string.h之strcat使用
查看>>
scikit-learn Quick Start
查看>>
剑指:不分行从上往下打印二叉树
查看>>
win8如何设置以管理员身份运行
查看>>
Linked List Cycle II
查看>>
深度学习——结构化机器学习项目(学习策略2)[9]
查看>>
P - Shopaholic
查看>>
21.tail命令
查看>>
JAVA的非对称加密算法RSA——加密和解密
查看>>