uva10034

8764 단어
제목 대의: 등에 있는 반점의 좌표를 주고 이 반점을 연결하는 데 가장 적은 잉크를 구한다.
사고방식:최소 생성 트리
코드:
#include <iostream>
using namespace std;
#include <cstring>
#include <stdio.h>
#include <cmath>
#include <algorithm>

double x[105],y[105];
double dis[5050];//i,j     
int flag[5050];//  
int jihe[5050];//i      
int u[5050],v[5050];
int n,m;
double sum;

int cmp(const int i,const int j) {
    return dis[i] < dis[j] ;
}
int find(int i) {
    if(jihe[i] == i)
        return i;
    else
        return jihe[i] = find(jihe[i]);
// return jihe[i] == i ? i : jihe[i] = find(jihe[i]);
}
void kruskal() {
    sum = 0;
    for(int i = 0; i < n; i++)
        jihe[i] = i;//          
    sort(flag,flag + m, cmp);
    for(int i = 0; i < m; i++) {
        int k = flag[i];
        int x = find(u[k]);
        int y = find(v[k]);
        if(x != y) {
            sum = sum + dis[k];
            jihe[x] = y;
        }
    }
}

int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
    // memset(flag,0,sizeof(flag));
    // memset(jihe,0,sizeof(jihe));
        for(int i = 0; i < n; i++)
            scanf("%lf %lf",&x[i],&y[i]);
        m = 0;
        for(int i = 0 ; i < n; i++) {
            for(int j = i + 1; j < n ; j++)  {
                dis[m] =sqrt((x[i] - x[j]) *(x[i] - x[j]) + (y[i] - y[j]) *(y[i] - y[j]));
                u[m] = i;
                v[m] = j;
                flag[m] = m++;
            }
        }
        kruskal();
        printf("%.2lf
"
,sum); if(T) printf("
"
); } return 0; }

prim:
#include <iostream>
using namespace std;
#include <stdio.h>
#include <cstring>
#include <cmath>
int n;
double x[105],y[105];
double w[105][105];
int pre[105];
double minCost[105];
int hash[105];
double Prim() {
    double sum = 0;
    memset(hash,0,sizeof(hash));
    hash[1] = 1;
    for(int i = 1; i <= n; i++) {
        minCost[i] = w[1][i];
        pre[i] = 1;
    }
    int u = -1;
    for(int i = 1; i < n; i++) {
        u = -1;
        for(int j = 1; j <= n; j++)
            if(!hash[j]) {
                if(u == -1 || minCost[j] < minCost[u])
                    u = j;
            }//        
        sum += w[pre[u]][u];
        hash[u] = 1;
        for(int j = 1; j <= n; j++)
            if(!hash[j]) {
                if(minCost[j] > w[u][j]) {
                    minCost[j] = w[u][j];
                    pre[j] = u;
            }// u         mincost   
        }
    }
    return sum;
}
int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        for(int i = 1; i <= n; i++) {
            scanf("%lf %lf",&x[i],&y[i]);
        }
        memset(w,0,sizeof(w));
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n; j++) 
                w[i][j] = sqrt((x[i] - x[j]) *(x[i] - x[j]) + (y[i] - y[j]) *(y[i] - y[j]));
        }
        printf("%.2lf
"
,Prim()); if(T) printf("
"
); } return 0; }

좋은 웹페이지 즐겨찾기