1. 程式人生 > >【bzoj3498】PA2009 Cakes 判斷三元環

【bzoj3498】PA2009 Cakes 判斷三元環

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; }