樱符「完全墨染的樱花」

题面暂时没有[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;
}
12-31 21:20