原題傳送門
這道題瞄了一眼還以為是spfa最短路。
後面發現距離為2.。
好像可以列舉中間點來著?
時間效率o(n*(2n-2))≈o(n^2)
boom!(ps:9018上過了,說明資料太水了。。)
然後我們看看能不能預處理。。
第一大和第二大可以預處理233~
然後sum(中間點的臨近點的權值總和)可以預處理。。。
然後就過了?o(n)
哦,對了忘記講演算法:
最大的聯合權值就是中間點的臨近點的第一大*第二大。。
所有的聯合權值。。
我們假設有三個點a,b,c 那麼聯合權值=ab+ac+ba+bc+ca+cb=a(b+c)+b(a+c)+c(a+b)=a(sum-a)+b(sum-b)+c(sum-c);
然後就可以o(n)啦!
o(∩_∩)o~~。。
下面先貼o(n^2)**
#include#include#include
#define mod 10007
using
namespace
std;
int n,num=0
;struct
edgeg[
400001
];int head[200001],sum=0
;int w[200001
];void ins(int x1,int
y1)void addedge(int x1,int
y1)int
main()
for(int i=1;i<=n;i++)
scanf("%d
",&w[i]);
int ans1=0,ans2=0
;
for(int i=1;i<=n;i++)
else
if(tmp>max2)
}ans1=max(ans1,max1*max2);
for(int j=head[i];j;j=g[j].next)
sum=0
; }
ans2=(ans2+mod)%mod;
printf(
"%d %d\n
",ans1,ans2);
return0;
}
再貼o(n)**(為啥比上面的還慢。。)
#include#include#include
#define mod 10007
using
namespace
std;
int n,num=0
;struct
edgeg[
200001
];int head[200001
];int w[200001
];int max1[200001],max2[200001
];int sum[200001
];void ins(int x1,int
y1)void work(int q,int
r)
else
if(w[q]>max2[r]) max2[r]=w[q];
}int
main()
for(int i=1;i<=n;i++)
scanf("%d
",&w[i]);
int ans1=0,ans2=0
;
for(int i=1;i)
for(int i=1;i<=n;i++)ans1=max(ans1,max1[i]*max2[i]);
for(int i=1;i)
ans2=(ans2+mod)%mod;
printf(
"%d %d\n
",ans1,ans2);
return0;
}
NOIP2014 聯合權值
鄰接表儲存樹。列舉每個節點,使之作為中點,先計算出與其相連的所有節點的權值總和l,與其相連的所有節點在該節點處形成的權值 l w w。如果沒有l,直接列舉以此節點為中點的節點對則只能過60 的資料。include include include include include include inc...
NOIP 2014 聯合權值
評測傳送 70分 列舉中間點,然後再兩層迴圈列舉這個點的所有鄰接點,兩兩相乘,加入和中。可能退化為n 2 100分 在70分的基礎上加乙個優化,當我們列舉了中間點,然後再列舉它的鄰接點 j 時,用sum i 表示 i 的所有鄰接點的權值的和,那麼以 i 作為中間點,j這個點對答案的貢獻為 sum i...
(noip2014)聯合權值
題目傳送門sxazr 本題可直接列舉每個點,然後列舉與它相連的兩個點,這兩個點的乘積便是乙個聯合權值 可以記錄下每個點與它相連的點的最大值和次大值,結果就是取最大值和次大值乘積的最大 求和的話,可以記錄下乙個點相連所有點的和s i sum w j s i w j j是與i相連的點 列舉每個點的sum...