1. 程式人生 > >bzoj3498: PA2009 Cakes

bzoj3498: PA2009 Cakes

ins ide 思路 its max cli eve view bzoj

題目描述:

N個點m條邊,每個點有一個點權a。
對於任意一個三元環(j,j,k)(i<j<k),它的貢獻
為max(ai,aj,ak)
求所有三元環的貢獻和。
N<100000,,m<250000。

算法標簽:三元環

思路:

裸的三元環模板題拉。

主要思路是按照度數排序對於雙向邊之連接度數大指向度數小的單向邊,這樣每個三元環只算一次。

效率是O(nlogm+mlogm)。

以下代碼:

技術分享圖片
#include<bits/stdc++.h>
#define il inline
#define LL long long
#define _(d) while(d(isdigit(ch=getchar())))
using
namespace std; const int N=1e5+5,M=25e4+5; LL ans; bool vis[N]; int n,m,a[N],in[N],head[N],ne[M],to[M],cnt; struct node{ int l,r; }t[M]; il int read(){ int x,f=1;char ch; _(!)ch==-?f=-1:f;x=ch^48; _()x=(x<<1)+(x<<3)+(ch^48); return f*x; } il void insert(int
x,int y){ ne[++cnt]=head[x]; head[x]=cnt;to[cnt]=y; } int main() { n=read();m=read(); for(int i=1;i<=n;i++)a[i]=read(); for(int i=1;i<=m;i++){ int x=read(),y=read(); in[x]++;in[y]++; t[i]=(node){x,y}; } for(int i=1;i<=m;i++){
int x=t[i].l,y=t[i].r; if(in[x]<in[y]||(in[x]==in[y]&&x>y))swap(x,y); insert(x,y); } for(int x=1;x<=n;x++){ for(int i=head[x];i;i=ne[i])vis[to[i]]=1; for(int i=head[x];i;i=ne[i]){ int v=to[i]; for(int j=head[v];j;j=ne[j]){ if(vis[to[j]]){ ans+=max(a[x],max(a[v],a[to[j]])); } } } for(int i=head[x];i;i=ne[i])vis[to[i]]=0; } printf("%lld\n",ans); return 0; }
View Code

bzoj3498: PA2009 Cakes