一道圖論好題
阿新 • • 發佈:2017-10-10
can 解釋 limit smart 之間 存在 cstring pac 題目
一道圖論好題
Time Limit:1000ms Memory Limit:128MB
題目描述
LYK有一張無向圖G={V,E},這張無向圖有n個點m條邊組成。並且這是一張帶權圖,不僅有邊權還有點權。
LYK給出了一個子圖的定義,一張圖G’={V’,E’}被稱作G的子圖,當且僅當
·G’的點集V’包含於G的點集V。
·對於E中的任意兩個點a,b∈V’,當(a,b)∈E時,(a,b)一定也屬於E’,並且連接這兩個點的邊的邊權是一樣的。
LYK給一個子圖定義了它的價值,它的價值為:點權之和與邊權之和的比。
LYK想找到一個價值最大的非空子圖,所以它來找你幫忙啦。
輸入格式
第一行兩個數n,m表示一張n個點m條邊的圖。
第二行n個數ai表示點權。
接下來m行每行三個數u,v,z,表示有一條連接u,v的邊權為z的無向邊。數據保證任意兩個點之間最多一條邊相連,並且不存在自環。
輸出格式
你需要輸出這個價值最大的非空子圖的價值,由於它是一個浮點數,你只需要保留小數點後兩位有效數字。
輸入樣例
3 3
2 3 4
1 2 3
1 3 4
2 3 5
輸出樣例
1.67
樣例解釋
選擇1,2兩個點,則價值為5/3=1.67。
對於20%的數據n=2
對於50%的數據n<=5
對於100%的數據1<=n,m<=100000,1<=ai,z<=1000。
題解
選擇連邊,價值為(a+c)/(b+d+e)。
不選,價值為max(a/b,c/d)。
易證max(a/b,c/d)>(a+c)/(b+d+e)。
證明過程:
假設a/b>=c/d,那麽a/b-c/d=(ad-bc)/bd>=0,所以ad-bc>=0。
所以a/b-(a+c)/(b+d)=(a(b+d)-b(a+c))/b(b+d)=(ad-bc)/b(b+d)>=0,所以a/b>=(a+c)/(b+d),所以a/b>(a+c)/(b+d+e)。
因為子圖非空,所以只選一條邊上的兩點一定最優。
代碼
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> using namespace std; const int N=100005; int n,m; int a[N]; double ans; int main(){ scanf("%d%d",&n,&m); for(i=1;i<=n;i++)scanf("%d",&a[i]);
int u,v,w; for(i=1;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); ans=max(ans,(double)(a[u]+a[v])/(double)w); } printf("%.2f\n",ans); return 0; }
一道圖論好題