http://acm.nyist.net/JudgeOnline/problem.php?pid=11
次小生成树:生成树权值第二小的生成树,当存在一条边跟最小生成树上的边相等时,次小生成树跟最小生成树相等。
题目解析:先用prim算法生成次小生成树,并且保存生成树上每个节点的前一个节点,并且保存生成树上用过的边,然后枚举没有用过的边,就会形成一个环,然后判断环上除新加入的边外的边有没有与加入的新边相等的,如果有相等的,就说明存在次小生成树。
代码如下:
#include<cstdio>
002.
#include<cstring>
003.
#include<algorithm>
004.
using
namespace
std;
005.
const
int
INF=0xffffff;
006.
int
map[505][505];
007.
int
pre[505];
008.
int
f[505][505];
009.
int
flag[505];
010.
int
dis[505];
011.
int
m,n;
012.
013.
014.
void
prim()
015.
{
016.
memset
(flag,0,
sizeof
(flag));
017.
int
pos=1;
018.
dis[1]=0;
019.
flag[1]=1;
020.
for
(
int
i=1;i<=n;i++)
021.
pre[i]=1;
022.
for
(
int
i=2;i<=n;i++)
023.
dis[i]=map[pos][i];
024.
for
(
int
j=1;j<n;j++)
025.
{
026.
int
Min=999999999;
027.
for
(
int
i=1;i<=n;i++)
028.
{
029.
if
(!flag[i]&&dis[i]<Min)
030.
{
031.
Min=dis[i];
032.
pos=i;
033.
}
034.
}
035.
int
q=pre[pos];
036.
flag[pos]=1;
037.
f[q][pos]=f[pos][q]=0;
038.
for
(
int
i=1;i<=n;i++)
039.
{
040.
if
(!flag[i]&&map[pos][i]<dis[i])
041.
{
042.
dis[i]=map[pos][i];
043.
pre[i]=pos;
044.
}
045.
}
046.
}
047.
048.
}
049.
int
cmst()
050.
{
051.
for
(
int
i=1;i<=n;i++)
//枚举在最小生成树上的每一个点
052.
{
053.
for
(
int
j=1;j<=n;j++)
054.
{
055.
if
(f[i][j])
//此边没有用过
056.
{
057.
int
t=map[i][j];
058.
int
v=i,v1=v;
059.
int
u=j;
060.
int
ff=0;
061.
while
(1)
062.
{
063.
if
(map[v1][pre[v1]]==t)
064.
{
065.
ff=1;
066.
break
;
067.
}
068.
if
(v1==u)
069.
break
;
070.
if
(v1==pre[v1])
071.
{
072.
ff=0;
073.
break
;
074.
}
075.
v1=pre[v1];
076.
}
077.
while
(!ff)
078.
{
079.
if
(map[u][pre[u]]==t)
080.
{
081.
ff=1;
082.
break
;
083.
}
084.
if
(v==u)
085.
break
;
086.
if
(u==pre[u])
087.
{
088.
ff=0;
089.
break
;
090.
}
091.
u=pre[u];
092.
}
093.
if
(ff)
return
1;
094.
}
095.
}
096.
}
097.
return
0;
098.
}
099.
int
main()
100.
{
101.
int
icase;
102.
scanf
(
"%d"
,&icase);
103.
while
(icase--)
104.
{
105.
106.
int
a,b,c;
107.
scanf
(
"%d%d"
,&n,&m);
108.
memset
(map,2,
sizeof
(map));
109.
memset
(f,0,
sizeof
(f));
110.
for
(
int
i=1;i<=m;i++)
111.
{
112.
scanf
(
"%d%d%d"
,&a,&b,&c);
113.
f[a][b]=f[b][a]=1;
114.
map[a][b]=map[b][a]=c;
115.
}
116.
prim();
117.
if
(cmst())
118.
printf
(
"Yes\n"
);
119.
else
120.
printf
(
"No\n"
);
121.
}
122.
return
0;
123.
}