pku 1679 次最小生成树

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
#include < iostream >
#include
< queue >
#include
< vector >
#define Nmax 105
#define INF 100000
using namespace std;
typedef
struct
{
int num;
int st;
}Node;
queue
< Node > q;
Node node;
int n,m,ANS,col[Nmax][Nmax],tree[Nmax],lowcost[Nmax],dir[Nmax],way[Nmax][Nmax],MAX[Nmax][Nmax],COL[Nmax][Nmax];
bool v[Nmax];

int Max( int a, int b)
{
if (a > b) return a;
return b;
}
void prim()
{
int k,j,i;
memset(v,
false , sizeof (v));
for (i = 0 ;i <= n;i ++ )
for (j = 0 ;j <= n;j ++ )way[i][j] = false ;
for (i = 1 ;i <= n;i ++ )
{
lowcost[i]
= col[i][ 1 ];
dir[i]
= 1 ;
}
tree[
0 ] = 1 ;
v[
1 ] = true ;
ANS
= 0 ;
for (k = 1 ;k < n;k ++ )
{
int min = INF;
int min_x;
for (j = 1 ;j <= n;j ++ )
{
if ( ! v[j] && lowcost[j] < min)
{
min
= lowcost[j];
min_x
= j;
}
}
v[min_x]
= true ;
tree[k]
= min_x;
ANS
+= min;
int t = dir[min_x];
way[t][min_x]
= true ;
way[min_x][t]
= true ;
for (j = 1 ;j <= n;j ++ )
{
if ( ! v[j] && lowcost[j] > col[j][min_x])
{
lowcost[j]
= col[j][min_x];
dir[j]
= min_x;
}
}
}
}


void BFS()
{
for ( int i = 1 ;i <= n;i ++ )
{
memset(v,
false , sizeof (v));
while ( ! q.empty())q.pop();
node.num
= 0 ;
node.st
= i;
q.push(node);
v[i]
= true ;
while ( ! q.empty())
{
node
= q.front();
int t = node.st;
int len = node.num;
MAX[i][t]
= node.num;
q.pop();
v[t]
= true ;
for ( int j = 1 ;j <= n;j ++ )
{
if (COL[t][j] !=- 1 &&! v[j])
{
node.st
= j;
node.num
= Max(len,COL[t][j]);
v[j]
= true ;
q.push(node);
}
}
}
}
}
void PRIN()
{
int i,j;
for ( i = 1 ;i <= n;i ++ )
{
for ( j = 1 ;j <= n;j ++ )
{
cout
<< MAX[i][j] << " " ;
}
cout
<< endl;
}
cout
<< endl;
}
bool Cal()
{
int i,j;
for ( i = 1 ;i <= n;i ++ )
for ( j = 1 ;j <= n;j ++ )
{
if (way[i][j])MAX[i][j] = COL[i][j] = col[i][j];
else MAX[i][j] = COL[i][j] =- 1 ;
}
// PRIN();


BFS();
// PRIN();
bool sign_2 = true ;
for (i = 1 ;i <= n && sign_2;i ++ )
for (j = 1 ;j <= n && sign_2;j ++ )
{
if ( ! way[i][j] && col[i][j] == MAX[i][j]){ sign_2 = false ; break ;}
}
return sign_2;
}

int main()
{
// freopen("input.txt","r",stdin);
int cas;
cin
>> cas;
while (cas -- )
{
scanf(
" %d%d " , & n, & m);
for ( int i = 0 ;i <= n;i ++ )
for ( int j = 0 ;j <= n;j ++ )col[i][j] = INF;
while (m -- )
{
int a,b,t;
scanf(
" %d%d%d " , & a, & b, & t);
col[a][b]
= t;
col[b][a]
= t;
}
prim();
// cout<<ANS<<endl;
if (Cal())cout << ANS << endl;
else cout << " Not Unique! " << endl;
}
return 0 ;
}

 

转载于:https://www.cnblogs.com/gdutbean/archive/2010/04/18/1714550.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值