• p4208 [JSOI2008]最小生成树计数


    分析

    此题难点在于一些最小生成树的性质

    可以参考这里

    https://www.cnblogs.com/Y-E-T-I/p/8462255.html

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define id(x) wh[sf(x)]
    const int mod = 31011;
    struct node {
        int x,y,z;
    };
    node d[1100];
    inline bool cmp(const node a,const node b){
        return a.z<b.z;
    }
    int fa[110],ffa[110],g[110][110],n,m,Ans,wh[110],cnt;
    inline int sf(int x){return x==fa[x]?x:fa[x]=sf(fa[x]);}
    inline int ssf(int x){return x==ffa[x]?x:ffa[x]=ssf(ffa[x]);}
    inline int gs(){
        int i,j,k,ans=1;
        for(i=1;i<cnt;i++)
          for(j=1;j<cnt;j++)
            g[i][j]=(g[i][j]%mod+mod)%mod;
        for(i=1;i<cnt;i++){
          for(j=i;j<cnt;j++)
            if(g[j][i])break;
          if(j>=cnt){
              puts("0");
              exit(0);
          }
          if(j!=i)ans=mod-ans,swap(g[i],g[j]);
          for(j=i+1;j<cnt;j++){
              while(g[j][i]){
                int t=g[i][i]/g[j][i];
                for(k=i;k<cnt;k++)
                  g[i][k]=(g[i][k]-1ll*t*g[j][k]%mod+mod)%mod;
                ans=mod-ans;
                swap(g[i],g[j]);
              }
          }
          ans=1ll*ans*g[i][i]%mod;
        }
        return ans;
    } 
    int main(){
        int i,j,k;
        Ans=1;
        scanf("%d%d",&n,&m);
        for(i=1;i<=m;i++)
          scanf("%d%d%d",&d[i].x,&d[i].y,&d[i].z);
        sort(d+1,d+m+1,cmp);
        for(i=1;i<=n;i++)fa[i]=i,wh[i]=++cnt;
        for(i=1;i<=m;i++){
          memset(g,0,sizeof(g));
          for(j=1;j<=cnt;j++)ffa[j]=j;
          int _=i,sum=0;
          while(_+1<=m&&d[_+1].z==d[_].z)_++;
          for(j=i;j<=_;j++){
              int x=d[j].x,y=d[j].y;
              if(id(x)==id(y))continue;
              g[id(x)][id(x)]++;
              g[id(y)][id(y)]++;
              g[id(x)][id(y)]--;
              g[id(y)][id(x)]--;
              if(ssf(id(x))!=ssf(id(y)))
              sum++,ffa[ssf(id(x))]=ssf(id(y));
          }
          for(j=1;j<n;j++)
            for(k=j+1;k<=n;k++)
              if(ssf(id(j))!=ssf(id(k))){
                  g[id(j)][id(j)]++;
                  g[id(k)][id(k)]++;
                  g[id(j)][id(k)]--;
                  g[id(k)][id(j)]--;
                  ffa[ssf(id(j))]=ssf(id(k));
              }
          if(!sum){
              i=_;
              continue;
          }
          Ans=1ll*Ans*gs()%mod;
          cnt=0;
          for(j=i;j<=_;j++){
              int x=d[j].x,y=d[j].y;
              if(sf(x)!=sf(y))fa[sf(x)]=sf(y);
          }
          memset(wh,0,sizeof(wh));
          for(j=1;j<=n;j++)
            if(!id(j))id(j)=++cnt;
          i=_;
          if(cnt==1)break;
        }
        if(cnt>1)puts("0");
          else printf("%d
    ",Ans);
        return 0;
    }
  • 相关阅读:
    ural 1519 fomular 1 既插头DP学习笔记
    2016集训测试赛(十九)Problem C: 无聊的字符串
    2016集训测试赛(十九)Problem A: 24点大师
    2016集训测试赛(二十)Problem B: 字典树
    写一个addEventListener以及removeEventListener
    关于props的注意事项!
    swiper轮播始终居中active图片
    vue中登录模块的插件封装
    v-show
    v-if
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/11413277.html
Copyright © 2020-2023  润新知