P6815 [PA2009] Cakes(三元环计数)
[PA2009] Cakes
题目描述
一个有
对于任意一个三元环
求所有三元环的贡献和。
我们可以给无向边定向,具体的做法是
度数小的连向度数大的。
度数相等,编号小的连向大的。
然后枚举i的每个出点j,进行标记。
再对每个j枚举出点k,若k被i标记,则形成一个三元环。
首先这是一个DAG,正确性是显然的。
考虑分析复杂度。
设
考虑j点
1.原图中
2.原图中
所以复杂度是
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<bitset>
#include<cmath>
#include<set>
#include<unordered_map>
#define fo(i,a,b) for (ll (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (ll (i)=(b);(i)>=(a);(i)--)
#define mk(x,y) make_pair((x),(y))
#define A puts("Yes")
#define B puts("No")
using namespace std;
typedef double db;
typedef long long ll;
//typedef __int128 i128;
const int N=3e5+10;
//const int S=1e5+5;
//const int inf=1ll<<60;
const int inf=1<<29;
const ll mo=1e9+7;
struct node{
int x,y;
};
node a[N];
int n,d[N],m,x,y;
vector<int> e[N];
int bz[N];
ll c[N];
int main()
{
// freopen("data.in","r",stdin);
scanf("%d %d",&n,&m);
fo(i,1,n) scanf("%lld",&c[i]);
fo(i,1,m) {
scanf("%d %d",&x,&y);
a[i]=(node){x,y};
d[x]++; d[y]++;
}
fo(i,1,m) {
x=a[i].x; y=a[i].y;
if (d[x]!=d[y]) {
if (d[x]>d[y]) swap(x,y);
e[x].emplace_back(y);
}
else {
if (x>y) swap(x,y);
e[x].emplace_back(y);
}
}
ll ans=0;
fo(i,1,n) {
for (int v:e[i]) bz[v]=i;
for (int j:e[i]) for (int k:e[j]) {
if (bz[k]==i) {
ans+=max(c[i],max(c[j],c[k]));
}
}
}
printf("%lld",ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】