最小生成树计数 WA on #10 90分求调
查看原帖
最小生成树计数 WA on #10 90分求调
1340759
ARIS2_0楼主2024/10/10 17:52

如题。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=210,maxm=2010,mod=31011;
int n,m;
struct edge{
    int s,e,v;
}e[maxm];
bool operator < (edge a,edge b){
    return a.v<b.v;
}
void init(){
    cin>>n>>m;
    for(int i=1;i<=m;i++)cin>>e[i].s>>e[i].e>>e[i].v;
}
int fa[maxn];
void csh(){
    for(int i=0;i<maxn;i++)fa[i]=i;
}
int find(int x){
    while(x!=fa[x])x=fa[x];
    return x;
}
void add(int a,int b){
    fa[find(a)]=find(b);
}
int lefts[maxn],rights[maxn],num;
void makeit(){
    int last=-1;
    sort(e+1,e+m+1);
    for(int i=1;i<=m;i++){
        if(last!=e[i].v){
            rights[num]=i-1;
            lefts[++num]=i;
            last=e[i].v;
        }
    }
    rights[num]=m;
}
int cnt[maxn];
bool Kruskal(){
    int tot=0;csh();
    for(int i=1;i<=m;i++){
        if(find(e[i].s)!=find(e[i].e)){
            tot++;
            add(e[i].s,e[i].e);
            cnt[upper_bound(lefts+1,lefts+num+1,i)-lefts-1]++;
            if(tot==n-1)break;
        }
    }
    return tot==n-1;
}
int dfsans;
void dfs(int i,int x,int choose){
    if(i==rights[x]+1){
        if(choose==cnt[x]){
            dfsans++;
            dfsans%=mod;
        }
        return;
    }
    if(rights[x]-i+1>cnt[x]-choose)dfs(i+1,x,choose);
    if(choose<cnt[x]){
        int p=find(e[i].s),q=find(e[i].e);
        if(p!=q){
            fa[p]=q;dfs(i+1,x,choose+1);
            fa[p]=p;
        }
    }
}
void BA(int x){
    for(int i=lefts[x];i<=rights[x];i++)add(e[i].s,e[i].e);
}
signed main(){
    init();makeit();
    if(!Kruskal()){
        cout<<0;return 0;
    }
    csh();int ans=1;
    for(int i=1;i<=num;i++){
        dfsans=0;
        dfs(lefts[i],i,0);
        ans*=dfsans;ans%=mod;
        BA(i);
    }
    cout<<ans;return 0;
}
2024/10/10 17:52
加载中...