标签:des style blog io os for sp 2014 问题
题意:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一条路即可,迭代+prim
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <set> #include <map> #include <stack> #include <queue> #include <vector> #include <string> #define for0(a,b) for(a=0;a<b;++a) #define for1(a,b) for(a=1;a<=b;++a) #define foru(i,a,b) for(i=a;i<=b;++i) #define ford(i,a,b) for(i=a;i>=b;--i) using namespace std; typedef long long ll; const int maxn = 1000 + 5; const int maxm = 100005; const int INF = 1e9; double x[maxn], y[maxn], z[maxn]; double cost[maxn][maxn], dist[maxn][maxn]; int n; double Dist(int i, int j) { return sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) ); } void init() { int i, j; for1(i,n) scanf("%lf%lf%lf", &x[i], &y[i], &z[i]); for1(i,n) foru(j,i+1,n){ dist[i][j] = dist[j][i] = Dist(i, j); cost[i][j] = cost[j][i] = fabs(z[i] - z[j]); } } int vis[maxn], pre[maxn]; double dis[maxn]; double prim(double p) { int i, j; memset(vis, 0, sizeof vis ); vis[1] = 1; foru(i,2,n) { dis[i] = cost[1][i]-dist[1][i]*p; pre[i] = 1; } double Cost = 0, Len = 0; for0(i,n-1){ double Mincost = INF; int k = -1; for1(j,n){ if(!vis[j] && dis[j]<Mincost){ Mincost = dis[k=j]; } } if(k==-1) break; vis[k] = 1; Cost += cost[pre[k]][k]; Len += dist[pre[k]][k]; for1(j,n){ double tmp = cost[k][j] - dist[k][j]*p; if(!vis[j]&&dis[j]>tmp){ dis[j] = tmp; pre[j] = k; } } } return Cost / Len; } void solve() { //牛顿迭代 double x0=0, x=0; while(true){ x = prim(x0); if(fabs(x-x0)<1e-4) break; x0 = x; } printf("%.3f\n", x); } int main() { #ifndef ONLINE_JUDGE freopen("in.cpp","r",stdin); freopen("out.cpp", "w", stdout); #endif // ONLINE_JUDGE int i, j; while(~scanf("%d", &n)) { if(n==0) break; init(); solve(); } return 0; }
标签:des style blog io os for sp 2014 问题
原文地址:http://blog.csdn.net/yew1eb/article/details/39673031