调了将近两个小时,一直tle,从优先级队列改成数组+排序 到改并查集结构,最后发现是给边开的数组不够大。。。
长记性了
两种形式的kurskal献上
第一种
#include <iostream>
#include <memory.h>
#include <queue>
#include <stdio.h>
using namespace std;
const int IN = (1<<28);
int N,cost,cnt;
struct Edage
{
int sou,des,len;
Edage( int ss = 0, int dd = 0, int ll = 0 ):sou(ss), des(dd), len(ll) {}
friend bool operator <( const Edage &a, const Edage &b )
{
return a.len > b.len;
}
};
priority_queue <Edage> Edages;
int id[100010];
void init_union()
{
for( int i = 1; i <= N; i++ )
id[i] = i;
}
int Find(int p)
{
return id[p];
}
void unit_union( int p, int q )
{
int idp = id[p];
int idq = id[q];
for( int i = 1; i <= N; i++ )
if( id[i] == idq )
id[i] = idp;
}
void kruskal()
{
while( !Edages.empty() && cnt != N-1 )
{
Edage now = Edages.top();
Edages.pop();
if( id[now.sou] == id[now.des] )
continue;
else
{
cnt++;
cost += now.len;
unit_union( now.sou, now.des );
}
}
}
int main()
{
while( scanf("%d", &N) , N )
{
cnt = 0;
memset(id, 0, sizeof(id));
while( !Edages.empty() )
Edages.pop();
int num = ((N-1) * N) / 2;
init_union();
while( num-- )
{
int Begin,End,Len,State;
scanf("%d %d %d %d", &Begin, &End, &Len, &State);
if( State )
{
if( id[Begin] != id[End] )
{
cnt ++ ;
unit_union( Begin, End );
}
}
else
{
Edages.push( Edage( Begin, End, Len ) );
}
}
cost = 0;
kruskal();
cout << cost << endl;
}
return 0;
}
第二种
#include <iostream>
#include <queue>
#include <memory.h>
#include <algorithm>
#include <stdio.h>
using namespace std;
struct Edage
{
int sou,des,length;
Edage( int ss = 0, int dd = 0, int ll = 0 ):sou(ss),des(dd),length(ll) {}
};
bool cmp( const Edage &a, const Edage &b)
{
return a.length < b.length;
}
Edage Es[100005];
int id[105];
int N,M,Cost;
void init_union()
{
for( int i = 1; i <= N; i++ )
{
id[i] = i;
}
}
int Find( int p )
{
while( p != id[p] )
p = id[p];
return p;
}
int Isconnect( int p, int q )
{
return Find(p) == Find(q);
}
void unit( int p, int q )
{
int pid = Find(p);
int qid = Find(q);
if( Find(p) == Find(q) )
return;
else
{
id[pid] = qid;
}
}
void kruskal()
{
init_union();
int cnt = 0;
for( int i = 0; i < M; i++ )
{
Edage now = Es[i];
int p = now.sou;
int q = now.des;
if( !Isconnect( p, q ) )
{
Cost += now.length;
unit( p, q );
cnt++;
if( cnt == N-1 )
break;
}
}
}
bool Judge()
{
int ID = Find(1);
for( int i = 1; i <= N; i++ )
if( Find(i) != ID )
return false;
return true;
}
int main()
{
while( scanf("%d", &N), N != 0 )
{
M = (N * (N-1))/2;
memset(id, 0, sizeof(id));
int t = 0;
for( int i = 0; i < M; i++ )
{
int state;
scanf("%d %d %d %d", &Es[i].sou, &Es[i].des, &Es[i].length, &state);
if( state )
Es[i].length = 0;
}
sort( Es, Es+M,cmp );
Cost = 0;
kruskal();
cout << Cost << endl;
}
return 0;
}