POJ1679

首先求出最小生成树,记录权值之和为MinST。然后枚举添加边(u,v),加上后必形成一个环,找到环上非(u,v)边的权值最大的边,把它删除,计算当前生成树的权值之和,取所有枚举加边后生成树权值之和的最小值

思路:

最小生成树唯一性判断,求次小生成树的val再与最小生成树比较。
1.先用prim算法求出最小生成树。并在其过程中保存加入到MST中的Max[i][j]( i 到 j 路径中的最大边 ) 
2.对未加入MST的边进行遍历:从MST中去掉i j路径中的最大边,加入未访问边G[i][j],如果得到的生成树的权值和MST的相等,则存在次小生成树的权值=MST的权值和

 #include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
#define INF 0x3f3f3f3f const int N = 1e3+;
int G[N][N]; // graph matrix
int f[N]; // pre node
int vis[N]; // visited node
int dis[N]; // main matrix: the edges(set-u)
int mark[N][N];
int Max[N][N]; // path from i to j max edge
int n,m,best; int prim(int v)
{
int ans=;
vis[v]=;
for(int i=;i<=n;i++)
{
dis[i]=G[v][i];
f[i]=v;
}
dis[v]=;
for(int i=;i<n;i++) // n-1
{
int u=-;
for(int j=;j<=n;j++)
if(!vis[j]&&(u==-||dis[j]<dis[u]))u=j;
if(u==-)break;
vis[u]=;
mark[u][f[u]] = mark[f[u]][u] = ;
ans += dis[u];
for(int j=;j<=n;j++)
{
// compare with visited node record path max edge
if(vis[j])Max[u][j]=Max[j][u]=max(Max[j][f[u]],dis[u]);
if(!vis[j]&&dis[j]>G[u][j])
{
dis[j]=G[u][j];
f[j]=u;
}
}
}
return ans;
} int SMST()
{
int mini=INF;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++) //or for(int j=i+1;j<=n;j++)
{
if(i!=j&&!mark[i][j])
mini = min(mini,best+G[i][j]-Max[i][j]);
}
return mini;
} int main()
{
int x,y,w,T;
scanf("%d",&T);
while(T--)
{
memset( vis, ,sizeof(vis) );
memset( Max, ,sizeof(Max) );
memset( f, ,sizeof(f) );
memset( dis, ,sizeof(dis) );
memset( mark, ,sizeof(mark) );
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
if(i==j)G[i][j]==;
else G[i][j]=INF;
}
for(int i=;i<m;i++)
{
scanf("%d%d%d",&x,&y,&w);
G[x][y]=w;
G[y][x]=w;
}
best = prim();
int temp = SMST();
if(temp == best)
printf("Not Unique!\n");
else
printf("%d\n",best);
}
return ;
}

CDOJ 1959

思路:这道题会出现重边,用Kruskal算法处理起来比较方便。(用邻接表方便,邻接矩阵还要考虑同两点之间的多条权值相同的边。)

次小生成树的权值如果等于最小生成树的权值, 其替换边只会是权值相同的边,于是可以把权值相同边放在一起考虑,分别判断全部没有合并时有多少可以合并(cnt1记录的是可以加入集合的边数),边合并边判断有多少可以合并(cnt2记录的是选中一条加入到集合),如果可选的大于构成最小生成树所需要的,那么就存在一种相同的边权可以替换原来的,从而最小生成树不唯一。

 #include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N = 2e5+;
struct Node
{
int u,v;
LL w;
}G[N]; int n,m;
int f[];
int find(int x)
{
return x==f[x]?x:f[x]=find(f[x]);
} bool cmp(Node & a, Node & b)
{
return a.w<b.w;
} void kruskal()
{
int cnt1=;
int cnt2=;
for(int i=;i<=n;i++)f[i]=i;
sort(G,G+m,cmp);
for(int i=;i<m;)
{
int j=i;
while(j<m&&G[j].w==G[i].w)
{
int u = find(G[j].u);
int v = find(G[j].v);
if(u!=v)cnt1++;
j++;
}
j=i;
while(j<m&&G[j].w==G[i].w)
{
int u = find(G[j].u);
int v = find(G[j].v);
if(u!=v){
cnt2++;
f[u]=v;
}
j++;
}
i=j;
if(cnt1>cnt2)break;
}
if( cnt1 > cnt2 ){
printf("zin\n");
}else{
printf("ogisosetsuna\n");
}
} int main()
{
int x,y;
LL w;
cin>>n>>m;
for(int i=;i<m;i++)
{
cin>>x>>y>>w;
G[i].u=x;
G[i].v=y;
G[i].w=w;
}
kruskal();
return ;
}

次小生成树(POJ1679/CDOJ1959)的更多相关文章

  1. POJ1679 The Unique MST[次小生成树]

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 28673   Accepted: 10239 ...

  2. POJ1679(次小生成树)

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 36692   Accepted: 13368 ...

  3. POJ1679(次小生成树)

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24201   Accepted: 8596 D ...

  4. POJ1679 The Unique MST【次小生成树】

    题意: 判断最小生成树是否唯一. 思路: 首先求出最小生成树,记录现在这个最小生成树上所有的边,然后通过取消其中一条边,找到这两点上其他的边形成一棵新的生成树,求其权值,通过枚举所有可能,通过这些权值 ...

  5. POJ1679 The Unique MST 【次小生成树】

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20421   Accepted: 7183 D ...

  6. 次小生成树(poj1679)

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20737   Accepted: 7281 D ...

  7. poj1679次小生成树入门题

    次小生成树求法:例如求最小生成树用到了 1.2.4这三条边,总共5条边,那循环3次的时候,每次分别不用1.2.4求得最小生成树的MST,最小的MST即为次小生成树 如下代码maxx即求最小生成树时求得 ...

  8. POJ1679 The Unique MST —— 次小生成树

    题目链接:http://poj.org/problem?id=1679 The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total S ...

  9. POJ-1679 The Unique MST,次小生成树模板题

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K       Description Given a connected undirec ...

随机推荐

  1. TCP连接的TIME_WAIT和CLOSE_WAIT 状态解说【转】

    相信很多运维工程师遇到过这样一个情形: 用户反馈网站访问巨慢, 网络延迟等问题, 然后就迫切地登录服务器,终端输入命令"netstat -anp | grep TIME_WAIT | wc ...

  2. python3+selenium框架设计10-发送邮件

    使用python3的email模块和smtplib模块可以实现发送邮件的动能.email模块用来生成email,smtplib模块用来发送邮件,接下来看如何在生成测试报告之后,并将报告放在邮件附件中并 ...

  3. Anaconda安装新模块

    如果使用import导入的新模块没有安装,则会报错,下面是使用Anaconda管理进行安装的过程:1.打开Anaconda工具,如图: 2.可通过输入 conda list 查看已安装的模块 3.如果 ...

  4. 前端 -----02 body标签中相关标签

    今日内容: 字体标签: h1~h6.<font>.<u>.<b>.<strong><em>.<sup>.<sub> ...

  5. 【原创】大叔问题定位分享(31)hive metastore报错

    hive metastore在建表时报错 [pool-5-thread-2]: MetaException(message:Got exception: java.net.ConnectExcepti ...

  6. JMeter 中_time 函数的使用(时间戳、当前时间)

    有时在接口测试时,其参数需要为时间戳或者是日期格式的数据.针对此问题,可以使用JMeter自带的_time 函数来解决以上问题 操作步骤: 1.通过函数助手,生成一个_time 函数: 2.如果参数为 ...

  7. Navicat系列产品激活教程

    准备 本教程可破解12.x版本,如果教程失效请联系我 # 19.1.11 破解暂时失效,请勿更新 (如已更新请卸载重新安装老版本,数据不会丢失 http://download.navicat.com/ ...

  8. hashtable——散列表

    2018-11-01 散列表---哈希表基于快速存取,时间换空间一种基于线性数组的线性表,不过元素之间并非紧密排列 散列函数--通过函数,有key关键码计算地址(相当于数组下标),函数尽可能使元素均匀 ...

  9. WebSocket服务端和客户端使用

    using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Net;usi ...

  10. Confluence 6 使用 Apache 和 mod_proxy 的基本配置

    在这些示例中,我们使用下面的信息: http://www.example.com/confluence - 你计划使用的 URL http://example:8090/ - Confluence 当 ...