标签: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