\ # 2020 겨울방학 합숙 훈련 \ # 최소 생 성 트 리 입문 (Minimum Spanning Tree) 코드 노트
23245 단어 2020 겨울방학 합숙 훈련알고리즘
정의.
생 성 트 리
알고리즘 사상 (욕심 - 욕심)
먼저 n 개의 정점 만 포함 하고 변 집 이 빈 자 도 를 만 들 고 자 도 에서 각 정점 을 각 나무의 뿌리 결점 으로 본 다음 에 그물 의 변 집 E 에서 가중치 가 가장 작은 변 을 선택한다. 만약 에 이 변 의 두 정점 이 서로 다른 나무 에 속 하면 자 도 를 넣 는 것 이다. 즉, 두 그루 의 나 무 를 한 그루 로 합성 하 는 것 이다. 반대로 이 변 의 두 정점 이 같은 나무 에 떨 어 졌 다 면.취 할 수 없 으 며, 다음 가중치 가 가장 작은 변 을 취하 여 다시 시도 해 야 한다.숲 속 에 나무 한 그루, 즉 서브 맵 에 n - 1 개의 변 이 들 어 있 을 때 까지 순서대로 유추 합 니 다.
실제 조작
#include
#include
#include
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e3+10;
int father[maxn];
int n,m,sum,cnt;
struct node
{
int st;
int ed;
int w;
}edge[maxn];
bool cmp(node x,node y)
{
return x.w<y.w;
}
void init()
{
for(int i=1;i<=n;i++) father[i]=i;
memset(edge,0,sizeof(edge));
}
int find(int x)
{
return x==father[x]?x:father[x]=find(father[x]);
}
void kruskal()
{
sum=0,cnt=0;
for(int i=1;i<=m;++i)
{
int fx=find(edge[i].st);
int fy=find(edge[i].ed);
if(fx==fy) continue;//
sum+=edge[i].w;
father[fx]=fy;
cnt++;// , , n-1
if(cnt==n-1) return;
}
}
int main()
{
while(~scanf("%d %d",&m,&n)&&m)
{
init();
for(int i=1;i<=m;i++) scanf("%d %d %d",&edge[i].st,&edge[i].ed,&edge[i].w);
sort(edge+1,edge+m+1,cmp);//
kruskal();
if(cnt==n-1) printf("%d
",sum);
else printf("?
");
}
}
프 림 (Prim) 알고리즘 (시간 복잡 도 O (n2))
알고리즘 사상 (탐욕 - 탐욕)
임의의 시간 에 최소 생 성 트 리 에 속 하 는 노드 집합 을 T 로 확정 하고 나머지 노드 집합 은 S 로 설정 합 니 다. 매번 에 가장 작은 한 변 (x, y, z) 을 찾 으 면 x * 8712 ° S, y * 8712 ° T 를 만족 시 킵 니 다.즉, 두 점 은 각각 S, T 의 가중치 가 가장 작은 변 에 속 한 다음 에 점 x 를 S 에서 삭제 하여 집합 T 에 넣 고 z 를 답안 에 누적 하 는 것 이다.
실제 조작
#include
#include
#include
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e3+10;
int cost[maxn][maxn];//
int mincost [maxn];
//mincost[u] u
int T,n,m,x,y,ans;
bool used[maxn];// i
int prim()
{
memset(mincost,inf,sizeof(mincost));// , inf
memset(used,false,sizeof(used));// ,
mincost[0]=0;// 0
ans=0;//
while(1)
{
int v=-1;//
//
for(int u=0;u<n;++u)
{
if(!used[u]&&(v==-1||mincost[u]<mincost[v])) v=u;
/*
( ) ( )
, , inf
*/
}
if(v==-1) break;// ,
used[v]=true;//
ans+=mincost[v];
for(int u=0;u<n;++u) mincost[u]=min(mincost[u],cost[v][u]);
//
/*
, mincost inf cost[0][u]
cost[0][u] 0 ( ),u
,
mincost, inf
*/
}
return ans;
}
int main()
{
while(~scanf("%d %d",&n,&m)&&n+m);
{
for(int i=0;i<m;i++) scanf("%d %d %d",&x,&y,&cost[x][y]);
printf("%d
",prim());
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【JavaScript】 볼록함 그라함 스캔을 구현, 애니메이션화한다! ? 【canvas】볼록포를 시각화해 본다. — s-yoshiki | 스크립트 카스 (@s_yoshiki_dev) JavaScript에서 그레이엄 스캔에 의해 정렬되어 가는 애니메이션을 구현했다. 아래쪽에서 데모로 소개. 참고 Java...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.