SPOJ:368 Cobbled streets

전형 적 인 제목 은 최소 생 성 트 리 를 구 하 는 것 이다.
여기 서 내 가 사용 하 는 것 은 크 루스 칼 알고리즘 이다.
kruskal 알고리즘 이 사용 하 는 탐욕 준칙 은 남 은 변 에서 순환 도로 가 생기 지 않 는 최소 비용 을 가 진 변 을 선택 하여 선택 한 변 의 집합 에 가입 하 는 것 입 니 다.선택 한 변 에 순환 도로 가 생기 면 생 성 나무 가 형성 되 지 않 는 다 는 것 을 알 게 되 었 다.kruskal 알고리즘 은 e 단계 로 나 뉘 는데 그 중에서 e 는 네트워크 의 가장자리 수량 입 니 다.소모 가 점차 증가 하 는 순서에 따라 이 e 변 을 고려 하고 매번 한 변 을 고려한다.어떤 쪽 을 고려 할 때 선택 한 쪽 의 집합 에 넣 으 면 순환 도로 가 나타 나 면 버 리 고 그렇지 않 으 면 선택 합 니 다.
 
집합 처리 로 고리 가 생 겼 는 지 확인 합 니 다.
father [find (a)] = find (b);여 기 는 두 개의 나무 뿌리 가 합 쳐 져 서 처음에는 WA 에 주의 하지 않 았 다.
생 성 트 리 변수 가 n - 1 에 도 착 했 을 때 최소 생 성 트 리 가 되 었 음 을 설명 하고 바로 뛰 어 나 올 수 있 습 니 다.이렇게 사용 할 때 는 좀 적 을 것 이다.
 
 
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct Edge
{
    int u,v,cost;
};
Edge a[300005];
int father[1005]={0};
int n,m;
bool cmp(Edge a,Edge b)
{
    return a.cost<b.cost;
}
void init_union_find()
{
    for(int i=1;i<=n;++i)
    father[i]=i;
}
int find(int p)
{
    return father[p]==p?p:find(father[p]);
}
void unite(int a,int b)
{
    father[find(a)]=find(b);
}
void Kruskal(int &ans)
{
   sort(a,a+m,cmp);
   init_union_find();
   int count=0;
   for(int i=0;i<m;++i)
   {
       Edge t=a[i];
       if(find(t.u)!=find(t.v))
       {
           unite(t.u,t.v);
           ans+=t.cost;
           count++;
           if(count==n-1) break;
       }
   }
}
int main()
{
   int T;
   scanf("%d",&T);
   while(T--)
   {
   int p,ans=0;
   scanf("%d%d%d",&p,&n,&m);
   for(int i=0;i<m;++i)
    scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].cost);
   Kruskal(ans);
   printf("%d
",p*ans); } return 0; }

좋은 웹페이지 즐겨찾기