POJ 1278 Agri - Net 최소 생 성 트 리 템 플 릿 문제 (Prim 과 Kruskal)
Prim 과 Kruskal 알고리즘 은 모두 최소 생 성 트 리 를 푸 는 효과 적 인 방법 이지 만 이들 의 효율 적 인 실현 은 모두 교묘 한 데이터 구조 에 의존한다.Kruskal 알고리즘 을 사용 하여 집합 을 찾 으 면 O (E * alpha (E)) 의 풀이 시간 (그 중에서 alpha 함 수 는 증가 와 느 린 함수 이 고 여기 서 상수 로 볼 수 있 습 니 다) 에 도달 할 수 있 습 니 다. 또한 정렬 시간 을 더 하면 총 시간 은 O (E log (E) 입 니 다. prim 알고리즘 에 서 는 최소 우선 대기 열 을 유지 하고 O (1) 를 요구 합 니 다.시간 내 에 요 소 를 찾 고 값 을 바 꾸 었 습 니 다. 저 는 좋 은 방법 을 알 지 못 했 습 니 다. 이 진 더미 의 요 소 를 찾 는 시간 은 O (n) 이기 때문에 배열 로 유지 하 는 것 이 좋 습 니 다.
poj 1278 문제 면 은 여기 서 더 이상 군말 하지 않 습 니 다. 바로 정점 < 100 의 최소 생 성 트 리 의 문제 입 니 다. 다음은 개인 코드 를 첨부 합 니 다. 프로 그래 밍 습관 은 camelVariant 명명 법 을 사용 합 니 다. 또한 변수 이름 이 비교적 길 기 때문에 많이 양해 해 주 십시오.
Prim 방법:
#include
#include
#define Size 101
typedef int iter;
int farms[Size][Size];
struct Vertex {
int key;
int piNumber;
bool isValid;
};
typedef struct Vertex Vertex;
Vertex vertices[Size];
int extractMin(int size)
{
int isNull = true;
int tempMin = INT_MAX;
int tempMinIndex = -1;
for (int i = 0; i < size; i++) {
if (!vertices[i].isValid)
continue;
else {
// printf("Here.
");
isNull = false;
if (tempMin > vertices[i].key) {
tempMinIndex = i;
tempMin = vertices[i].key;
}
}
}
// printf("TempMinIndex:%d
", tempMinIndex);
if (!isNull) {
vertices[tempMinIndex].isValid=false;
}
return tempMinIndex;
}
bool isBeLong(int size,int checkNumber)
{
return vertices[checkNumber].isValid && size > checkNumber;
}
int main()
{
iter i, j, k;
int size,temp;
while (scanf("%d", &size) != EOF) {
for (i = 0; i < size; i++)
for (j = 0; j < size; j++)
scanf("%d", &farms[i][j]);
/* for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
printf("%d", farms[i][j]);
j == size - 1 ? printf("
") : printf("\t");
}
}*/
for (i = 0; i < size; i++) {
vertices[i].piNumber = -1;
vertices[i].key =1000000;
vertices[i].isValid = true;
}
temp = extractMin(size);
while (temp >= 0) {
// printf("Temp:%d
", temp);
for (i = 0; i < size; i++) {
if (i != temp) {
if (farms[temp][i] < vertices[i].key&&isBeLong(size, i)) {
vertices[i].piNumber = temp;
vertices[i].key = farms[temp][i];
}
}
}
temp = extractMin(size);
}
int value = 0;
for (int i = 0; i < size; i++)
value += farms[i][vertices[i].piNumber];
printf("%d
", value);
}
return 0;
}
Kruskal 방법:
#include
#include
#include
#include
#include
using namespace std;
struct Edge {
int from;
int to;
int weight;
bool operator < (const Edge& ele) {
return this->weight < ele.weight;
}
};
typedef struct Edge Edge;
class KruskalGraph
{
public:
void init(int n)
{
this->edges.clear();
this->vertices.clear();
for (int i = 0; i < n; i++)
this->vertices.push_back(-1);
this->treeEdges.clear();
this->order = n;
}
void Inserto(int u, int v, int w)
{
Edge tempEdge;
tempEdge.from = u;
tempEdge.to = v;
tempEdge.weight = w;
this->edges.push_back(tempEdge);
}
void Kruskal()
{
sort(edges.begin(), edges.end());
int count = 0;
for (int i = 0; i < edges.size()&&counttreeEdges.push_back(edges[i]);
Union(root1, root2);
count++;
}
}
}
void showMST()
{
for (int i = 0; i < treeEdges.size(); i++) {
printf("(%d,%d,%d) ", treeEdges[i].from, treeEdges[i].to, treeEdges[i].weight);
}
printf("
");
}
int mstValu()
{
int ret = 0;
for (int i = 0; i < treeEdges.size(); i++)
ret += treeEdges[i].weight;
return ret;
}
private:
vector edges;
vector treeEdges;
vector vertices;
int order;
void Union(int x, int y)
{
int root1, root2;
root1 = Find(x);
root2 = Find(y);
//printf("Roots:%d %d
", root1, root2);
_union(root1, root2);
}
int Find(int x)
{
if (vertices[x] < 0)
return x;
else
return vertices[x] = Find(vertices[x]);
}
void _union(int x, int y)
{
if (vertices[y] < vertices[x]) {
vertices[x] = y;
}
else {
if (vertices[x] == vertices[y])
vertices[x]--;
vertices[y] = x;
}
}
};
int main()
{
int n;
KruskalGraph graph;
while (scanf("%d", &n) != EOF) {
graph.init(n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int weight;
scanf("%d", &weight);
if (i > j)
graph.Inserto(i, j, weight);
}
}
graph.Kruskal();
//graph.showMST();
printf("%d
", graph.mstValu());
}
return 0;
}
그리고 오늘 배 운 두 개의 템 플 릿 을 동봉 합 니 다.
하나의 집합:
class UnionFindSet : vector
{
public:
UnionFindSet(int k)
{
this->clear();
for (int i = 0; i < k; i++) {
this->push_back(-1);
}
}
void show()
{
for (int i = 0; i < this->size(); i++) {
printf("%d ", (*this)[i]);
}
printf("
");
}
int find(int x)
{
if ((*this)[x] < 0)
return x;
else
return (*this)[x] = find((*this)[x]);
}
void Union(int x, int y)
{
int root1, root2;
root1 = find(x);
root2 = find(y);
printf("Roots:%d %d
", root1, root2);
_union(root1, root2);
}
private:
void _union(int x, int y)
{
if ((*this)[y] < (*this)[x]) {
(*this)[x] = y;
}
else {
if ((*this)[x] == (*this)[y])
(*this)[x]--;
(*this)[y] = x;
}
}
};
또 다른 사람의 Binary Indexed Tree 는 내일 맨 해 튼 트 리 를 풀 때 쓸 수 있 는 문 제 를 먼저 배 워 보 세 요.
class BinTree : vector
{
public:
explicit BinTree(int k = 0) {
assign(k + 1, 0);
}
int sum(int k)
{
return k > 0 ? sum(k - lowBit(k)) + (*this)[k] : 0;
}
int last()
{
return size() - 1;
}
void add(int k, int w)
{//for adding w to node k
if (k > last())
return;
(*this)[k] += w;
add(k + lowBit(k), w);
}
void show(int start, int end)
{
for (int i = start; i <= end; i++) {
printf("%d ", (*this)[i]);
}
printf("
");
}
void show()
{
for (int i = 0; i < this->size(); i++) {
printf("%d ", (*this)[i]);
}
printf("
");
}
private:
int lowBit(int k)
{
return k&-k;
}
};
오늘 은 여기까지 쓰 겠 습 니 다. 상술 한 기술적 인 세부 사항 은 제 가 나중에 글 을 쓰 는 과정 에서 시간 이 있 을 때 언급 하 겠 습 니 다. 앞으로 도 잘 부탁드립니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
PAT 1094 구 글 채용메모: 1. subString 왼쪽 닫 고 오른쪽 열 기 2, 0 은 출력 을 보충 해 야 합 니 다. 그렇지 않 으 면 형식 이 잘못 되 었 습 니 다....
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.