Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 23180 | Accepted: 8235 |
Description
Input
Output
Sample Input
2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2
Sample Output
3 Not Unique!
Source
对于最小生成树(可以用kruskal和prime算法求得,在这里我是用kruskal求得,如果不会请自己百度。),边的权值的和最小称为最小生成树。
而次小生成树就是除了最小生成树外的最小生成树。而且所有的次小生成树都是通过最小生成树的换边得到的。
所以难点就是如何换边。
对于如何换边:
1.先求出最小生成树,值为x。
2.一一枚举添加不在生成树上的边(这时候一定形成了一个环)
3.寻找环上的(最小生成树上的边)权值最大值与你所添加不在生成树上的边的权值比较,所得到的差值为min。
由于是一一枚举添加边,min有多个,求出最小的哪一个,所以次小生成树就为x+min。
昨天虽然把这道题A了,可是看到讨论区的测试数据发现自己又一个没有过,然而却AC了。然后今天起床就来研究研究。。。
发现我的程序是在找最大值,可是如果一个环有分支,它还会去找分支里面的最大值,于是就又优化了一下。
用的优先队列。
先附上第一次做的代码:
#include
#include
#include
using namespace std;
struct node
{
int a,b,cost;
}c[10005];
int fa[105],tree[105][105],vis[10005],vis_tree[105];//vis数组是对m对数据的标记vis_tree是对最小生成树标记
int n,m,max1;
bool cmp(node x,node y)
{
if(x.cost
#include
#include
#include
#include
using namespace std;
struct node1
{
int a,b,cost;
friend bool operator<(node1 x,node1 y )
{
return x.costs;
struct node
{
int a,b,cost;
}c[10005];
int fa[105],tree[105][105],vis[10005],vis_tree[105];
int n,m,max1,flag1;
bool cmp1(node x,node y)
{
if(x.cost