Description
N个点m条边,每个点有一个点权a。
对于任意一个三元环(j,j,k)(i< j< k),它的贡献
为max(ai,aj,ak)
求所有三元环的贡献和。
N<100000,,m<250000。
Input
The first line of the standard input contains two integers n and m (1<=N<=100000,1<=M<=250000) separated by a single space and denoting the number of confectioners at the convention and the number of pairs of them that like each other. The participants of the convention are numbered from 1 to N, The second line contains n integers pi (1<=Pi<=1000000) separated by single spaces and denoting the requirements of respective confectioners for flour (in decagrams). The following m lines contain data about pairs of contestants that like each other. Each of these lines contains two integers ai and bi (1<=ai,bi<=n Ai<>Bi) separated by a single space. They denote that confectioners ai and bi like each other. We assume that all pairs of participants of the convention apart from the ones listed in the input would not like to bake cakes together. Each pair of confectioners appears at most once in the input.
Output
The first and only line of the standard output should contain a single integer - the quantity of flour that will be used by all teams in total, in decagrams.
Sample Input
5 7
1 5 3 4 2
1 2
2 3
5 2
4 3
3 1
1 4
5 1
Sample Output
14
Explanation of the example. The following three-person teams: (1,2,3),(1,2,5) and (1,3,4)require 5, 5 and 4 decagrams of flour to bake the cakes. In total 5+5+4=14 decagrams of flour are required.
题解
对于每条边我们从大的点向小的点连边。
从小到大枚举点i,再枚举其连向的点x
如果x的出边大于根号m 则枚举与i相连的其他点y(y< x)是否与x相连。
否则枚举与x相连的点y是否与i相连。累加答案即可。
代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>
#include<complex>
#define ll long long
#define mod 10000007
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int tot,n,m,a[100005],Head[100005],Next[250005],ret[250005],du[100005];
set<int>s[100005];
ll ans;
struct node{int x,y;}e[250005];
inline void ins(int u,int v)
{
ret[++tot]=v;Next[tot]=Head[u];Head[u]=tot;
}
inline bool cmp(node a,node b)
{
return (a.x==b.x)?a.y<b.y:a.x<b.x;
}
int main()
{
n=read();m=read();
for (int i=1;i<=n;i++) a[i]=read();
for (int i=1;i<=m;i++)
{
e[i].x=read();e[i].y=read();
if (e[i].x<e[i].y) swap(e[i].x,e[i].y);
du[e[i].x]++;
}
sort(e+1,e+m+1,cmp);
for (int i=1;i<=m;i++)
{
ins(e[i].x,e[i].y);
s[e[i].x].insert(e[i].y);
}
int blo=sqrt(m);
for (int i=3;i<=n;i++)
for (int j=Head[i];j;j=Next[j])
{
int x=ret[j];
if (du[x]>blo)
{
for (int k=Next[j];k;k=Next[k])
{
int y=ret[k];
if (y>=x) continue;
if (s[x].find(y)!=s[x].end())
ans+=max(a[i],max(a[x],a[y]));
}
}
else
{
for (int k=Head[x];k;k=Next[k])
{
int y=ret[k];
if (s[i].find(y)!=s[i].end())
ans+=max(a[i],max(a[x],a[y]));
}
}
}
cout<<ans;
return 0;
}