樱符「完全墨染的樱花」
题面暂时没有[cry]
Solution
他给出的图一定是一棵仙人掌。
考虑仙人掌上的一个环,把环上最小的边删除并加到其他边上,这颗仙人掌的最大流不会变。
那么就是一棵树了。
对于树,我们把边按权值从大到小加入,同时维护$ \sum p^i $ 和 $\sum p^{n*(i-1)}$就行
#include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #define maxn 300005 #define mod 998244353 #define ll long long using namespace std; int n,m,P,M[maxn],head[maxn],flag[maxn],f[maxn],tot=1,dfn[maxn],low[maxn],sc; int ins[maxn],zh[maxn],top; ll ans,s[maxn],sn[maxn]; struct node{ int u,v,nex,w,fl; }e[1000006],E[1000006]; void add(int t1,int t2,int t3){ e[++tot].v=t2;e[tot].u=t1;e[tot].w=t3;e[tot].nex=head[t1];head[t1]=tot; } void dfs(int k,int fa){ zh[++top]=fa;dfn[k]=++sc;ins[k]=1; for(int i=head[k];i;i=e[i].nex){ if(i==(fa^1))continue; if(!dfn[e[i].v]){ dfs(e[i].v,i); } else if(ins[e[i].v]){ int Min=e[i].w,pl=i; for(int j=top;j>=0;j--){ int x=zh[j];if(e[x].w<Min)Min=e[x].w,pl=x; if(e[x].u==e[i].v)break; } E[pl/2].fl=1;E[i/2].w+=Min; for(int j=top;j>=0;j--){ int x=zh[j];E[x/2].w+=Min; if(e[x].u==e[i].v)break; } } } top--;ins[k]=0; } bool cmp(node A,node B){ return A.w>B.w; } int getf(int k){return f[k]==k?k:f[k]=getf(f[k]);} ll work(ll a,ll num){ ll A=1;for(;num;num>>=1,a=a*a%mod)if(num&1)A=A*a%mod;return A; } int main(){ cin>>n>>m>>P; for(int i=1,t1,t2,t3;i<=m;i++){ scanf("%d%d%d",&t1,&t2,&t3); add(t1,t2,t3);add(t2,t1,t3); E[i]=(node){t1,t2,0,t3,0}; } dfs(1,0); sort(E+1,E+m+1,cmp); for(int i=1;i<=n;i++)f[i]=i,s[i]=work(P,i),sn[i]=work(P,1LL*(i-1)*(n)); for(int i=1;i<=m;i++){ if(E[i].fl)continue; int t1=E[i].u,t2=E[i].v; int f1=getf(t1),f2=getf(t2); ans=ans+1LL*E[i].w*((sn[f1]*s[f2]%mod+sn[f2]*s[f1]%mod)%mod)%mod; ans%=mod; f[f1]=f2;(s[f2]+=s[f1])%=mod;(sn[f2]+=sn[f1])%=mod; } cout<<ans<<endl; return 0; }