description


analysis

  • 无向图上任意两点最大流不超过\(2\),说明该图是仙人掌

  • 由于最大流等于最小割,如果一条边在两个环里,断掉两个端点至少需要\(3\)的代价

  • 对于该仙人掌,求两点间的最小割,那么要么割一条桥边,要么割一个环上的两条边

  • 环上边权最小边一定要割,那就把这条边断开,环上其他边边权加上该边边权,相当于提前割

  • 然后图就变成了一棵树,任意两点间最小割即为路径最小值

  • 把\(n-1\)条树边从大到小插入,这样前面的不会影响到后面的贡献

  • 并查集维护每一个集合的\(\sum p^{(i-1)n},\sum p^i\),由于分配律所以两个集合的贡献相乘就是整个集合的贡献

  • 我一开始\(naive\)认为要用\(tarjan\)缩环,打了才发现我还\(too\) \(young\)

  • \(m\)条边降序排序后先直接构树,记录构成环的边,然后找这些边端点\(LCA\),暴力把路径上的边权加上

  • 注意不要太过暴力,身经百战后倍增也是很重要的


code

#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 300005
#define MAXM 500005
#define ha 998244353
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define rep(i,a) for (reg i=last[a];i;i=next[i]) using namespace std; ll last[MAXM*2],next[MAXM*2],tov[MAXM*2],len[MAXM*2];
ll fa[MAXN],falen[MAXN],depth[MAXN];
ll sumin[MAXN],sumi[MAXN],anc[MAXN][20];
ll n,m,p,tot,ans,cnt;
bool bz[MAXN]; struct edge
{
ll x,y,z;
}a[MAXM],b[MAXM]; inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline ll max(ll x,ll y){return x>y?x:y;}
inline ll min(ll x,ll y){return x<y?x:y;}
inline bool cmp(edge a,edge b){return a.z>b.z;}
inline ll getfa(ll x){return fa[x]==x?x:fa[x]=getfa(fa[x]);}
inline ll pow(ll x,ll y)
{
ll z=1;
while (y){if (y&1)z=z*x%ha;x=x*x%ha,y>>=1;}
return z;
}
inline ll lca(ll x,ll y)
{
if (depth[x]<depth[y])swap(x,y);
fd(i,19,0)if (depth[anc[x][i]]>=depth[y])x=anc[x][i];
if (x==y)return x;
fd(i,19,0)if (anc[x][i]!=anc[y][i])x=anc[x][i],y=anc[y][i];
return anc[x][0];
}
inline void link(ll x,ll y,ll z){next[++tot]=last[x],last[x]=tot,tov[tot]=y,len[tot]=z;}
inline void dfs(ll x,ll y)
{
fo(i,1,19)anc[x][i]=anc[anc[x][i-1]][i-1];
rep(i,x)if (tov[i]!=y)fa[tov[i]]=anc[tov[i]][0]=x,falen[tov[i]]=len[i],depth[tov[i]]=depth[x]+1,dfs(tov[i],x);
}
int main()
{
freopen("T2.in","r",stdin);
//freopen("sakura.in","r",stdin);
//freopen("sakura.out","w",stdout);
n=read(),m=read(),p=read();
fo(i,1,n)fa[i]=i;
fo(i,1,m)a[i].x=read(),a[i].y=read(),a[i].z=read();
sort(a+1,a+m+1,cmp);
fo(i,1,m)
{
ll x=a[i].x,y=a[i].y,z=a[i].z,xx=getfa(x),yy=getfa(y);
if (xx!=yy)fa[xx]=yy,link(x,y,z),link(y,x,z);
else b[++cnt].x=x,b[cnt].y=y,b[cnt].z=z;
}
depth[1]=1,dfs(1,0),tot=0;
fo(i,1,cnt)
{
ll x=b[i].x,y=b[i].y,z=b[i].z,LCA=lca(x,y);
if (LCA!=x){falen[x]+=z;while (fa[x]!=LCA)x=fa[x],falen[x]+=z;}
if (LCA!=y){falen[y]+=z;while (fa[y]!=LCA)y=fa[y],falen[y]+=z;}
}
fo(i,2,n)a[++tot].x=i,a[tot].y=fa[i],a[tot].z=falen[i];
sort(a+1,a+n,cmp);
fo(i,1,n)sumin[i]=pow(p,(i-1)*n),sumi[i]=pow(p,i),fa[i]=i;
fo(i,1,n-1)
{
ll x=a[i].x,y=a[i].y,z=a[i].z,xx=getfa(x),yy=getfa(y);
(ans+=(z*sumin[xx]%ha*sumi[yy]%ha+z*sumin[yy]%ha*sumi[xx]%ha)%ha)%=ha;
fa[xx]=yy,(sumin[yy]+=sumin[xx])%=ha,(sumi[yy]+=sumi[xx])%=ha;
}
printf("%lld\n",ans);
return 0;
}

【JZOJ6376】樱符[完全墨染的樱花]的更多相关文章

  1. 9 Days 停课修炼题解集

    xj4604 排序 \(n,k <= 1e5\). 先考虑二分出这个值,check 有多少段的平均值小于这个 mid,这个在之前的复活赛中是原题 T4,数形结合,$ \text{Average} ...

  2. 【带权并查集】【HDU3038】【How Many Answers Are Wrong】d s

    这个题看了2天!!!最后看到这篇题解才有所明悟 转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4298091.html   ---by 墨染之樱 ...

  3. hdu3038 How Many Answers Are Wrong【基础种类并查集】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4298091.html   ---by 墨染之樱花 题目链接:http://acm.hdu.ed ...

  4. poj2486 Apple Tree【区间dp】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4374766.html   ---by 墨染之樱花 [题目链接]http://poj.org/p ...

  5. HYSBZ1588 营业额统计【Splay】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4366582.html   ---by 墨染之樱花 [题目链接]http://www.lydsy ...

  6. hdu5115 Dire Wolf【区间dp】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4361169.html   ---by 墨染之樱花 [题目链接]http://acm.hdu.e ...

  7. poj1144 Network【tarjan求割点】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4319585.html   ---by 墨染之樱花 [题目链接]http://poj.org/p ...

  8. poj1236 Network of Schools【强连通分量(tarjan)缩点】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4316263.html  ---by 墨染之樱花 [题目链接]http://poj.org/pr ...

  9. poj2342 Anniversary party【树形dp】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4316097.html   ---by 墨染之樱花 [题目链接]http://poj.org/p ...

随机推荐

  1. java-day24

    JDBC控制事务: 1.事务:一个包含多个步骤的业务操作,如果这个业务操作被事务管理,则这个步骤要么同时成功,要么同时失败. 2. 操作:         1. 开启事务         2. 提交事 ...

  2. python全栈开放实践第三版第一章的练习题完成情况

    练习题: 1.简述编译型与解释型语言的区别,且分别列出你知道哪些语言属于编译型,哪些数以解释型.1 编译型:只须编译一次就可以把源代码编译成机器语言,后面的执行无须重新编译,直接使用之前的编译结果就可 ...

  3. JavaScript中的面向对象编程,详解原型对象及prototype,constructor,proto,内含面向对象编程详细案例(烟花案例)

    面向对象编程:   面向:以什么为主,基于什么模式 对象:由键值对组成,可以用来描述事物,存储数据的一种数据格式 编程:使用代码解决需求   面向过程编程:         按照我们分析好的步骤,按步 ...

  4. Spring开发案例1半注解开发

    dao层: package cn.mepu.dao.imp; import cn.mepu.dao.AccountDao; import cn.mepu.domain.Account; import ...

  5. zmq中的router和dealer

    https://segmentfault.com/q/1010000000638839 在zeromq的guide里,它用router/dealer模式做了一个broker client对应ZMQ_R ...

  6. svg实现绘制路径动画

    1,首先用svg绘制一条path路径,然后进行如下操作 ps: 下面是svg中两个属性及值的意义 stroke-dasharray是让你指定画出的线段每段的长度,第二个值是各段之间空隙的长度. str ...

  7. leetcood学习笔记-203-移除链表元素

    题目描述: 方法:#在改pre链表时 head中的值也改变 class Solution(object): def removeElements(self, head, val): "&qu ...

  8. Servlet - request对象相关

    request对象中封装了当前请求的所有请求信息, request对象由Tomcat服务器创建, 并作为实参传递给处理请求的Servlet的service()方法 1. 获取请求头数据 // 获取请求 ...

  9. idea中添加mysql驱动jia包的方法

    1 将相关jar包拷贝到自己所建的lib 文件夹下  如下图所示 2   选中自己的module  接着选择Project Structure 如下图 3 接着如下图继续操作 如上图完成后  那么我们 ...

  10. 【NOI2019模拟2019.7.1】为了部落 (生成森林计数,动态规划)

    Description: \(1<=n<=1e9,1<=m,k<=100\) 模数不是质数. 题解: 先选m个点,最后答案乘上\(C_{n}^m\). 不妨枚举m个点的度数和D ...