最小生成树唯一性问题
Memory: 824K Time: 157MS
https://code.csdn.net/snippets/1632570
题意
RT.输入一张图,判断它的最小生成树是否唯一。
如果唯一,则输出这个生成树的值。否则输出Not Unique!
分析
如果最小生成树不是唯一的,那么肯定存在另一棵MST,它的边和第一次求出的MST不完全相同,但是值的和一样。
所以,求出第一棵树,枚举它的每一条边,删除之,再求MST,值相同则不唯一(此时求出的这棵新树即为另一棵MST)。如果值不同,记着把这条边恢复回去,再试其他边。
出现的问题
- 没注意到是无向图
(纯粹是秀逗) - 算完一组数据忘了清空
edge[].del=false
WA - 去掉边后整张图可能变得不连通,这时求出的最小生成树值无意义。数据里刚好有不连通图没考虑到就Not Unique的,所以WA
解决方案:求完mst,看是不是加入了所有点(Prim)
for(int i=1; i<=n; ++i)
if(!vis[i]) return 0x3f3f3f3f;
技巧
1.同一个求最小生成树的算法过程,可以记录边,可以不记录边。
inline int prim(int *sav=0)
//传入sav则保存边,否则不保存
if(sav) *(sav++)=e;
2.特别的存储方式,正向边反向边快速转换
通过^1的方式,同时删除一对边
for(int i=1; i<=m; ++i)
{
//...
addedge(2*i, s, t, w);
addedge(2*i+1, t, s, w);
}
//...
for(int i=1; i<=n-1; ++i)
{
edge[mst[i]].del=true;
edge[mst[i]^1].del=true;
//...
edge[mst[i]].del=false;
edge[mst[i]^1].del=false;
}