好蛋疼啊,由於double 不能用memset,害的我調了乙個多小時才發現。由於用二分搜尋,時間有點大
#include #include #include #include #define maxn 1005using namespace std;
const int inf = 0x3f3f3f;
struct nodenode[maxn];
double d[maxn];
double g[maxn][maxn];
double cost[maxn][maxn];
double benefit[maxn][maxn];
int n;
double mid,ans;
void calculate(int i,int j)
void makemap()
return;
}void prim()
if(!vis[i] && lowdist[i] < mindist)
} s = point;
ans += mindist;
num++;
} return;
}int main()
while(cin>>n && n)
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
double r=10000000,l=0.0;
while( (r-l)>1e-6 )
makemap();
prim();
if(ans >= 0) l = mid;
else r = mid;
} printf("%.3lf\n",l);
} return 0;
}
還是迭代好上面的用時2500多ms,而這個只要297ms,空間複雜度是降不下來了。
#include #include #include #include #define maxn 1005using namespace std;
const int inf = 0x3f3f3f;
struct nodenode[maxn];
double d[maxn];
double g[maxn][maxn];
double cost[maxn][maxn];
double benefit[maxn][maxn];
int n;
double mid,ans;
void calculate(int i,int j)
void makemap()
return;
}void prim()l[maxn];
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++) l[i].lowdist = inf;
int point;
ans = 0.0;
int s=1;
int num=1;
double suma = 0.0,sumb = 0.0;
while(true)
if(!vis[i] && l[i].lowdist < mindist)
} int a = l[point].s;
suma += cost[a][point];
sumb += benefit[a][point];
s = point;
num++;
} ans = suma/sumb;
return;
}int main()
while(cin>>n && n)
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
mid = 0.5;
while( true)
makemap();
prim();
if(abs(ans -mid) < 1e-6) break;
else mid = ans;
} printf("%.3lf\n",ans);
} return 0;
}
poj2728 最優比率生成樹
這個題的意思是給你乙個連通圖,圖上每個點都有連個權值ai,bi讓你選乙個生成樹使得sigma ai xi sigma bi xi 最小,對比與基礎的01規劃,我們假設答案是mid,然後建立乙個圖,其新的邊的權值是ai mid bi,然後求解最小生成樹,假設其答案是tp,如果tp 0,說明還有更優的解...
poj 2728 最優比率生成樹
思路 設sum cost i sum dis i r 那麼要使r最小,也就是minsum cost i r dis i 那麼就以cost i r dis i 為邊權重新建邊。當求和使得最小生成樹的 sum cost i r dis i 0時,這個r就是最優的。這個證明是01分數規劃。include ...
POJ2728 最優比率生成樹
一張 n 個結點 m 條邊的無向圖,每條邊有兩個權值 a,b 求一顆生成樹滿足樹上的所有邊 a 權和與 b 權和的商最大。1 n,m 1e4 0 1分數規劃 從長度為 n 的數列 和 中選出若干對,使得選出的 a 之和與 b 之和商最大。即求一組 x i 1 i n,x i 0 or 1 最大化 f...