1. 程式人生 > 實用技巧 >[暑假集訓]資料結構&簡單圖論專題1 Eddy's picture

[暑假集訓]資料結構&簡單圖論專題1 Eddy's picture

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <climits>
#include <algorithm>
using namespace std;
int n;
typedef struct{//邊單元
    int from ;
    int to;
    double w;//長度
}node;
typedef struct{ double x , y;}coordinate;//點單元
vector<coordinate>datas;//
所有的點 vector<node>edge;//所有的邊 int head[120]; double lowc[120]; int vis[120]; void init(){ datas.clear(); edge.clear(); for(int i = 0; i < 120; i ++){ vis[i] = 0; lowc[i] = INT_MAX; head[i] = -1; } } bool cmp(node a , node b){//比較兩邊 if(a.from == b.from && a.to == b.to) return
a.w < b.w ; if(a.from == b.from) return a.to < b.to ; return a.from < b.from ; } double dist(coordinate a , coordinate b){ double x = a.x - b.x ; double y = a.y - b.y ; return sqrt(x*x + y*y); } void input(){ coordinate temp; for(int i = 0; i < n; i ++){ scanf(
"%lf%lf",&temp.x , &temp.y); datas.push_back(temp); } node temp1; for(int i = 0; i < n; i ++) for(int j = i + 1; j < n; j ++){ temp1.from = i; temp1.to = j; temp1.w = dist(datas[i] , datas[j]); edge.push_back(temp1); temp1.from = j; temp1.to = i;//新增所有可能的邊 edge.push_back(temp1); } sort(edge.begin() , edge.end() , cmp);//排序 //以 from - to - 長度 依次比較 head[0] = 0; for(int i = 1; i < (int)edge.size(); i ++){ if(edge[i].from != edge[i-1].from){ head[edge[i].from] = i; } }//記錄以某一點為from的邊在edge裡第一次出現的地方。 } double prim(){ double res = 0; for(int i = head[0]; edge[i].from == 0 && i < n; i ++){ lowc[edge[i].to] = edge[i].w ; }//lowc表示以一點到i點最短邊長度 vis[0] = 1;//0點已放入lowc int u ; double minc ; for(int i = 1; i < n; i ++){ minc = INT_MAX; for(int j = 0; j < n; j ++){ if(!vis[j] && lowc[j] < minc ){ minc = lowc[j];//記錄lowc裡從某點出發最小邊長度 u = j;//記錄另一點的序號 } } if(minc == INT_MAX) return -1; res += minc ; vis[u] = 1; for(int j = head[u]; edge[j].from == u && j < (int)edge.size(); j ++){ //以u為開頭的所有邊 if(!vis[edge[j].to] && lowc[edge[j].to] > edge[j].w){ //如果出現比之前記錄的lowc更短的 lowc[edge[j].to] = edge[j].w; } } } return res; } int main(){ while(scanf("%d",&n)!=EOF){ init(); input(); printf("%.2lf\n",prim()); } return 0; }

https://vjudge.net/contest/384914#problem/B