暴力做法 记录相同权值的边区间若判断i 和i+1 边下标从0开始 wa
查看原帖
暴力做法 记录相同权值的边区间若判断i 和i+1 边下标从0开始 wa
331161
Orang楼主2020/6/25 09:42
#include<cstdio>
#include<algorithm>
#define N 120
#define M 1100
#define Mod 31011
using namespace std;
int fa[N],sum;

struct Node{
    int u,v,w;
    bool operator < (const Node &x)const{
        return w<x.w;
    }
}edge[M];

struct section{
    int l,r,num;
}sec[M];

void init(int n){
    for(int i=1;i<=n;i++)
        fa[i]=i;
}

int find(int x){
    return fa[x]==x?x:find(fa[x]);
}

void dfs(int x,int now,int cnt){
    int a,b;
    if(now == sec[x].r+1){
        if(cnt == sec[x].num)
            sum++;
        return;
    }
    a=find(edge[now].u);
    b=find(edge[now].v);
    if(a!=b){
        fa[a]=b;
        dfs(x,now+1,cnt+1);
        fa[a]=a,fa[b]=b;
    }
    dfs(x,now+1,cnt);
}

int main(){
    int n,m,a,b,cnt=0,cnt0=0,ans=1;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
        scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
    sort(edge,edge+m);
    init(n);
    for(int i=0;i<m-1;i++){
        if(edge[i].w!=edge[i+1].w){
            sec[cnt].r=i;
            sec[++cnt].l=i+1;
        }
        a=find(edge[i].u);
        b=find(edge[i].v);
        if(a!=b){
            fa[a]=b;
            sec[cnt].num++;
            cnt0++;
            //if(cnt0 == n-1) break;
        }
    }
    sec[cnt].r=m-1;
    if(cnt0 != n-1){
        printf("0\n");
        return 0;
    }
    init(n);
    for(int i=0;i<=cnt;i++){
        sum=0;
        dfs(i,sec[i].l,0);
        ans=(ans*sum)%Mod;
        for(int j=sec[i].l;j<=sec[i].r;j++){
            a=find(edge[j].u);
            b=find(edge[j].v);
            if(a!=b)
                fa[a]=b;
        }
    }
    printf("%d\n",ans);
    return 0;
}
2020/6/25 09:42
加载中...