`
人生难得糊涂
  • 浏览: 114372 次
社区版块
存档分类
最新评论

poj1679-次小生成树

 
阅读更多

说下求次小生出树的思路。 先求得最小生成树。

然后枚举不在生成树上的边E(i),将它加入到最小生成树上,则一定会形成一个环,我们把这个环上的最大边删掉,还是一个生成树。得到其权值W(i)  。min(W(i))即是次小生成树

具体实现时这样更简单:求得最小生成树权值min.

求在最小生成树上,任意两点之间的路径上的最大边,并用二维数组maxed[][]记录下来。 (调用多次spfa()实现)。

枚举所有不在生成树上的边,将其加入到最小生成树,并删除掉该环中在最小生成树上的最大边

则可以得到权值为

ans[i] = min+edge[i].w-maxed[u][v]

取ans的最小值即是次小生成树。

 

#include "iostream"
#include "algorithm"
#include "queue"
using namespace  std;
#define  MAXSIZE 110
#define  INF 999999
int t,m,n;
struct node
{
	int u;
	int v;
	int w;
	int flag;
};
node edge[MAXSIZE*MAXSIZE];
queue<int>que;
int f[MAXSIZE];
int e;
int kt;//最小生成树的权值
int vis[MAXSIZE];
int maxed[MAXSIZE][MAXSIZE];
int head[MAXSIZE];
int next[MAXSIZE];
int dis[MAXSIZE];
void addnode(int u,int v,int w,int f)
{
	edge[e].u=u;
	edge[e].v=v;
	edge[e].w=w;
	edge[e].flag=f;
	next[e]=head[u];
	head[u]=e++;

}
bool cmp(node &a,node &b)
{
	return a.w<b.w;
}
int findset(int x)
{
	if (x==f[x])
		return x;
	else
		return f[x]=findset(f[x]);

}
int kruskal()
{
	sort(edge,edge+e,cmp);
	int tot=0;
	int i;
	for (i=1;i<=n;i++)
	{
		f[i]=i;
	}
	for (i=0;i<e;i++)
	{
		if (findset(edge[i].u)!=findset(edge[i].v))
		{
			//union
			f[findset(edge[i].v)]=findset(edge[i].u);
			tot+=edge[i].w;
			edge[i].flag=1;
		}
	}
	return tot;
}
void spfa(int s)
{
	while(!que.empty())
	{
		que.pop();
	}
	memset(vis,0,sizeof(vis));
	que.push(s);
	vis[s]=1;
	int i;
	for (i=1;i<=n;i++)
	{
		dis[i]=INF;
	}
	dis[s]=0;
	while(!que.empty())
	{
		int t=que.front();
		que.pop();
		for ( i=head[t];i!=-1;i=next[i])
		{
			
			if (edge[i].flag&&dis[edge[i].v]>dis[t]+edge[i].w)
			{
				dis[edge[i].v]=dis[t]+edge[i].w;
				if (maxed[s][edge[i].v]<edge[i].w)
				{
					maxed[edge[i].v][s]=maxed[s][edge[i].v]=edge[i].w;
				}
				if (!vis[edge[i].v])
				{
					vis[edge[i].v]=1;
					que.push(edge[i].v);
				}
			}
			
		}
	}
}
int judge()
{
	int min=INF;
	//枚举所有不在生成树上的边
	for (int i=0;i<e;i++)
	{
		if (!edge[i].flag)
		{
			//ans = min+edge[i].w-maxed[u][v]
			int tans=kt+edge[i].w-maxed[edge[i].u][edge[i].v];
			if (min>tans)
			{
				min=tans;
			}
		}
	}
	//cout <<min<<endl;
	return min==kt;
}
int main()
{
	//freopen("in.txt","r",stdin);
	scanf("%d",&t);
	while(t--)
	{
		e=0;
		scanf("%d%d",&n,&m);
		memset(head,-1,sizeof(head));
		memset(next,-1,sizeof(next));
		memset(maxed,-1,sizeof(maxed));
		while(m--)
		{
			int a,b,c;
			scanf("%d%d%d",&a,&b,&c);
			addnode(a,b,c,0);
		}
		//求得最小生成树的权值
		 kt=kruskal();
	//	cout<<"kt: "<<kt<<endl;
		
		//bfs 求得点遍历生成树最大的边
		for (int i=1;i<=n;i++)
		{
			maxed[i][i]=0;
			spfa(i);
		}
		//判断是否具有次小生成树
		if (judge())
			printf("Not Unique!\n");
		else
			printf("%d\n",kt);

	}
	return 0;
}

 

 

 
1
0
分享到:
评论

相关推荐

    次小生成树(POJ 1679 The Unique MST)

    先利用prim算法求出最小生成树,然后通过往MST里加边来判断新生成的最小生成树是否具有最小的权值,POJ上The Unique MST(1679)题是要求判断最小生成树是否唯一,此题其实根本不用这样做,但是为了练习球次小生成树...

    POJ 1751 求最小生成树prim算法(JAVA)

    NULL 博文链接:https://128kj.iteye.com/blog/1705139

    poj1251 最小生成树

    NULL 博文链接:https://200830740306.iteye.com/blog/603493

    POJ 1789 最小生成树之prim算法

    NULL 博文链接:https://128kj.iteye.com/blog/1704752

    POJ 1639 Picnic Planning 最小度限制生成树

    最小度限制生成树的求法也不是很难,先把度被限制的那个点(s点)去掉,求一次MST,然后把s到各个连通分量的最小权值的边加上,然后继续加边看看能否使生成树权减小(详见解题报告)。

    度限制最小生成树源码

    度限制最小生成树代码 摘自POJ1639代码

    poj-solve:算法练习

    Algorithm-Java Algorithms + Data Structures = Programs. ——Niklaus Wirth 没日没夜地写程序。看到这几个字我两眼一黑,仿佛这就是我未来的生活。 为了摆脱这种焦虑心理,我逐步...最小生成树(prim,kruskal)(p

    pojacm题目具体分类

    4.图论 //Dijkstra、最小生成树、网络流 5.数论 //解模线性方程 6.计算几何 //凸壳、同等安置矩形的并的面积与周长 7.组合数学 //Polya定理 8.模拟  9.数据结构 //并查集、堆 10.博弈论  //表示举例 非主流...

    poj2485.rar_poj2485

    北大2485的简单题目。用了最小生成树,在VS上编译,并成功提交。

    POJ 1861 Network

    利用并查集判断环路,以及快速排序计算最小生成树

    北大oj 题目分类

    (3)最小生成树算法(prim,kruskal) (poj1789,poj2485,poj1258,poj3026) (4)拓扑排序 (poj1094) (5)二分图的最大匹配 (匈牙利算法) (poj3041,poj3020) (6)最大流的增广路算法(KM算法). (poj1459,poj3436) .....

    poj解题报告2395

    虽然A过了觉得简单,但要注意点小问题,而且我哇的时候没有找到解题报告,所以希望能对没A的人有点小帮助

    acm_code_20053565

    acm code of 20053565 poj onlinejudge 高精度 DP 图论 算法 最大流 最小生成树 线段树

    数据结构课程设计

    通过学习STL中的队列的实现原理解决了一道应用题:北大poj网上的Catch That Cow题目。还有最小生成树的应用的课程设计

    一个好的 pku 题目分类

    4.图论 //Dijkstra、最小生成树、网络流 5.数论 //解模线性方程 6.计算几何 //凸壳、同等安置矩形的并的面积与周长 7.组合数学 //Polya 定理 8.模拟 9.数据结构 //并查集、堆 10.博弈论 1、 排序 2、 搜索、回溯、...

    浙江大学ACM模板 计算几何,图论,数据结构,经典题的模板

    8.8 最小生成树(kruskal) 172 8.9 最短路径 173 8.10 最大网络流 175 8.11 最小费用流 180 8.12 最大团问题 182 8.13 二分图匹配 184 8.14 带权的最优二分图匹配 184 9.搜索算法概略 187 9.1 迭代深搜+IDA* 187 9.2 ...

    算法之路 ,成功掌握各种算法

    2.最小生成树(先写个prim,kruscal要用并查集,不好写) 3.大数(高精度)加减乘除 4.二分查找. (代码可在五行以内) 5.叉乘、判线段相交、然后写个凸包. 6.BFS、DFS,同时熟练hash表(要熟,要灵活,代码要简) ...

    挑战程序设计竞赛(第2版)

    2.5.5 最小生成树 2.5.6 应用问题 2.6 数学问题的解题窍门 2.6.1 辗转相除法 2.6.2 有关素数的基础算法 2.6.3 模运算 2.6.4 快速幂运算 2.7 一起来挑战GCJ的题目(1) 2.7.1 Minimum Scalar Product 2.7.2 Crazy ...

    kuangbin acm模板超级好用

    2.6 随机素数测试和大数分解 (POJ 1811) . . . . . . . . . . . . . . . . . . . . . . . 29 2.7 欧拉函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 2.7.1 分解质因素求...

Global site tag (gtag.js) - Google Analytics