bzoj 1016 [JSOI2008]最小生成树计数——matrix tree(相同权值的边为阶段缩点)(码力)...

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1016

就是缩点,每次相同权值的边构成的联通块求一下matrix tree。注意gauss里的编号应该是从1到...的连续的。

学习了一个TJ。用了vector。自己曾写过一个只能过样例的。都放上来吧。

路径压缩的话会慢?循环里ed[i].w!=ed[i+1].w的话会慢?

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=105,M=1005,mod=31011;
int n,m,fa[N],pa[N],c[N][N],a[N][N],ans=1;//ans=1
bool vis[N];
vector<int> v[N];
struct Ed{int x,y,w;bool operator< (const Ed &b)const{return w<b.w;}
}ed[M];
int find(int a,int f[]){return f[a]==a?a:find(f[a],f);} //加上路径压缩会变慢!!! 
int gauss(int n)
{bool fx=0;int ret=1;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)a[i][j]%=mod;//
  for(int i=1;i<=n;i++){int k=i;for(int j=i+1;j<=n;j++)if(abs(a[j][i])>abs(a[k][i]))k=j;if(k!=i){fx=!fx;for(int j=i;j<=n;j++)swap(a[i][j],a[k][j]);}for(int j=i+1;j<=n;j++)while(a[j][i]){fx=!fx;int tmp=a[i][i]/a[j][i];for(int l=i;l<=n;l++){int tp=a[i][l];a[i][l]=a[j][l];//i=ja[j][l]=(tp-tmp*a[j][l])%mod;//j=i%j
          }}(ret*=a[i][i])%=mod;}return (ret*(fx?-1:1)+mod)%mod;
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)fa[i]=i,pa[i]=i;for(int i=1;i<=m;i++)scanf("%d%d%d",&ed[i].x,&ed[i].y,&ed[i].w);sort(ed+1,ed+m+1);for(int i=1;i<=m+1;i++)//
    {if(ed[i-1].w!=ed[i].w||i==m+1)//
    {for(int j=1;j<=n;j++){if(!vis[j])continue;v[find(j,pa)].push_back(j);vis[j]=0;}for(int j=1;j<=n;j++){if(v[j].size()<=1)continue;memset(a,0,sizeof a);//!int siz=v[j].size();for(int l0=0;l0<siz;l0++)for(int l1=l0+1;l1<siz;l1++){int x=v[j][l0],y=v[j][l1],t=c[x][y];//x=v[j][l0],don't use l0 directlya[l0+1][l0+1]+=t;a[l1+1][l1+1]+=t;a[l0+1][l1+1]-=t;a[l1+1][l0+1]-=t;//but here is l0/1, for in gauss the bh must from 1 and be continous
          }(ans*=gauss(siz-1))%=mod;for(int k=0;k<siz;k++)fa[v[j][k]]=j;//fa -> pa
        }for(int j=1;j<=n;j++){fa[j]=pa[j]=find(j,fa);v[j].clear();}}int f1=find(ed[i].x,fa),f2=find(ed[i].y,fa);if(f1==f2)continue;vis[f1]=1;vis[f2]=1;pa[find(f1,pa)]=find(f2,pa);c[f1][f2]++;c[f2][f1]++;}for(int i=1;i<n;i++)if(find(i,fa)!=find(i+1,fa)){printf("0");return 0;}printf("%d",ans);return 0;
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=105,M=1005,mod=31011;
int n,m,fa[N],pa[N],c[N][N],a[N][N],ans=1;//ans=1
bool vis[N];
vector<int> v[N];
struct Ed{int x,y,w;bool operator< (const Ed &b)const{return w<b.w;}
}ed[M];
int find(int a,int f[]){return f[a]==a?a:find(f[a],f);} //加上路径压缩会变慢!!! 
int gauss(int n)
{bool fx=0;int ret=1;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)a[i][j]%=mod;//
  for(int i=1;i<=n;i++){int k=i;for(int j=i+1;j<=n;j++)if(abs(a[j][i])>abs(a[k][i]))k=j;if(k!=i){fx=!fx;for(int j=i;j<=n;j++)swap(a[i][j],a[k][j]);}for(int j=i+1;j<=n;j++)while(a[j][i]){fx=!fx;int tmp=a[i][i]/a[j][i];for(int l=i;l<=n;l++){int tp=a[i][l];a[i][l]=a[j][l];//i=ja[j][l]=(tp-tmp*a[j][l])%mod;//j=i%j
          }}(ret*=a[i][i])%=mod;}return (ret*(fx?-1:1)+mod)%mod;
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)fa[i]=i,pa[i]=i;for(int i=1;i<=m;i++)scanf("%d%d%d",&ed[i].x,&ed[i].y,&ed[i].w);sort(ed+1,ed+m+1);for(int i=1;i<=m;i++){int f1=find(ed[i].x,fa),f2=find(ed[i].y,fa);if(f1!=f2){vis[f1]=1;vis[f2]=1;pa[find(f1,pa)]=find(f2,pa);c[f1][f2]++;c[f2][f1]++;}
//      if(f1==f2)continue;//!!!!!!!if(ed[i+1].w!=ed[i].w||i==m){for(int j=1;j<=n;j++){if(!vis[j])continue;v[find(j,pa)].push_back(j);vis[j]=0;}for(int j=1;j<=n;j++){if(v[j].size()<=1)continue;memset(a,0,sizeof a);//!int siz=v[j].size();for(int l0=0;l0<siz;l0++)for(int l1=l0+1;l1<siz;l1++){int x=v[j][l0],y=v[j][l1],t=c[x][y];//x=v[j][l0],don't use l0 directlya[l0+1][l0+1]+=t;a[l1+1][l1+1]+=t;a[l0+1][l1+1]-=t;a[l1+1][l0+1]-=t;//but here is l0/1, for in gauss the bh must from 1 and be continous
          }(ans*=gauss(siz-1))%=mod;for(int k=0;k<siz;k++)fa[v[j][k]]=j;//fa -> pa
        }for(int j=1;j<=n;j++){fa[j]=pa[j]=find(j,fa);v[j].clear();}}}for(int i=1;i<n;i++)if(find(i,fa)!=find(i+1,fa)){printf("0");return 0;}printf("%d",ans);return 0;
}
改一下循环(慢?)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=105,M=1005,mod=31011;
int n,m,p0,p1,col[N],cnt,head[N],xnt,fnw,ans=1,fa[N],bh[N],tot;
bool used[M<<1],vis[N],nd[N],tvis[N];
struct Ed{int next,x,y,w;Ed(int x=0,int y=0,int w=0):x(x),y(y),w(w) {}bool operator< (const Ed &b)const{return w<b.w;}
}ed[M<<1];
struct Matrix{int a[N][N];void init(){memset(a,0,sizeof a);}Matrix operator- (const Matrix &b)const{Matrix c;c.init();for(int i=1;i<tot;i++)for(int j=1;j<tot;j++)c.a[i][j]=(a[i][j]-b.a[i][j])%mod;//
        return c;}
}d,l,r;
int find(int a){return fa[a]==a?a:fa[a]=find(fa[a]);}
void add(int x,int y,int w)
{ed[++xnt]=Ed(x,y,w);ed[++xnt]=Ed(y,x,w);if(find(x)!=find(y))fa[find(x)]=find(y);
}
void dfst(int cr)
{tvis[cr]=1;bh[cr]=++tot;for(int i=head[cr],v;i;i=ed[i].next)if(used[i]&&!tvis[ed[i].y])dfst(ed[i].y);
}
void dfsx(int cr,int f)    //dfs处理好这一块的度数矩阵和邻接矩阵 
{vis[cr]=1;for(int i=head[cr],v;i;i=ed[i].next)if(used[i]&&(v=ed[i].y)!=f){d.a[bh[cr]][bh[cr]]++;if(!vis[v])d.a[bh[v]][bh[v]]++;l.a[bh[cr]][bh[v]]=l.a[bh[v]][bh[cr]]=1;if(!vis[v])dfsx(v,cr);}
}
void gauss()
{int fx=1,ret=1;for(int i=1;i<tot;i++)//<tot,少一行一列 
    {int nw=i;for(int j=i+1;j<tot;j++)if(abs(r.a[j][i])>abs(r.a[nw][i]))nw=j;if(nw!=i){fx=-fx;for(int l=i;l<tot;l++)swap(r.a[i][l],r.a[nw][l]);}for(int j=i+1;j<tot;j++)while(r.a[j][i]){int tmp=r.a[i][i]/r.a[j][i];for(int l=i;l<tot;l++){int tp=r.a[i][l];r.a[i][l]=r.a[j][l];//i=j;r.a[j][l]=(tp-r.a[j][l]*tmp)%mod;//j=i%j
                }fx=-fx;}(ret*=r.a[i][i])%=mod;    //不要在上面赋值:消下面的时候可能换过来! 
    }ret=(ret*fx+mod)%mod;(fnw*=ret)%=mod;
}
void cal(int x)    //当前权值的一个个联通块 
{d.init();l.init();memcpy(tvis,vis,sizeof vis);tot=0;//bh!dfst(x);dfsx(x,0);r=d-l;gauss();
}
void dfs(int cr)
{col[cr]=cnt;for(int i=head[cr];i;i=ed[i].next)if(used[i]&&!col[ed[i].y])dfs(ed[i].y);
}
void solve()    //一层 
{memset(nd,0,sizeof nd);memset(used,0,sizeof used);for(int i=p0;i<=p1;i++)if(ed[i].x!=ed[i].y)    //边的两边连的是已经缩点后的 used[i]=1,nd[ed[i].x]=1,nd[ed[i].y]=1;    //能用的边和涉及的点 memset(vis,0,sizeof vis);memset(bh,0,sizeof bh);fnw=1;for(int i=1;i<=cnt;i++)if(!vis[i]&&nd[i])cal(i);    //每个联通块 (ans*=fnw)%=mod;cnt=0;memset(col,0,sizeof col);        //cnt:现在有多少点(缩点后)for(int i=1;i<=cnt;i++)if(!col[i])cnt++,dfs(i);        //缩点 for(int i=p1+1;i<=xnt;i++)ed[i].x=col[ed[i].x],ed[i].y=col[ed[i].y];
}
int main()
{scanf("%d%d",&n,&m);int x,y,w;for(int i=1;i<=n;i++)fa[i]=i;for(int i=1;i<=m;i++)scanf("%d%d%d",&x,&y,&w),add(x,y,w);for(int i=2;i<=n;i++)if(find(i-1)!=find(i)){printf("0");return 0;}//
    sort(ed+1,ed+xnt+1);cnt=n;for(int i=1;i<=xnt;i++){ed[i].next=head[ed[i].x];head[ed[i].x]=i;}for(int i=1;i<=xnt;i++){p0=i;while(ed[i+1].w==ed[i].w)i++;p1=i;solve();}printf("%d",ans);return 0;
}
只能过样例的

 

转载于:https://www.cnblogs.com/Narh/p/9274486.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/389221.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

区块链的模型结构

关于区块链的模型结构问题&#xff0c;行业内已经谈论千万遍了&#xff0c;基本上已经成为一种定义式的问题了。总体上来看&#xff0c;区块链的基础架构可以分为六层&#xff0c;包括数据层、网络层、共识层、激励层、合约层、应用层。每一层分别完成一项核心的功能&#xff0…

数据科学家 数据工程师_数据科学家应该对数据进行版本控制的4个理由

数据科学家 数据工程师While working in a software project it is very common and, in fact, a standard to start right away versioning code, and the benefits are already pretty obvious for the software community: it tracks every modification of the code in a p…

JDK 下载相关资料

所有版本JDK下载地址&#xff1a; http://www.oracle.com/technetwork/java/archive-139210.html 下载账户密码&#xff1a; 2696671285qq.com Oracle123 转载于:https://www.cnblogs.com/bg7c/p/9277729.html

商米

2019独角兽企业重金招聘Python工程师标准>>> 今天看了一下商米的官网&#xff0c;发现他家的东西还真的是不错。有钱了&#xff0c;想去体验一下。 如果我妹妹还有开便利店的话&#xff0c;我会推荐他用这个。小巧便捷&#xff0c;非常方便。 转载于:https://my.osc…

C#生成安装文件后自动附加数据库的思路跟算法

using System; using System.Collections.Generic; using System.Windows.Forms; using System.Data.SqlClient; using System.Data; using System.ServiceProcess; namespace AdminZJC.DataBaseControl { /// <summary> /// 数据库操作控制类 /// </summary> …

python交互式和文件式_使用Python创建和自动化交互式仪表盘

python交互式和文件式In this tutorial, I will be creating an automated, interactive dashboard of Texas COVID-19 case count by county using python with the help of selenium, pandas, dash, and plotly. I am assuming the reader has some familiarity with python,…

不可不说的Java“锁”事

2019独角兽企业重金招聘Python工程师标准>>> 前言 Java提供了种类丰富的锁&#xff0c;每种锁因其特性的不同&#xff0c;在适当的场景下能够展现出非常高的效率。本文旨在对锁相关源码&#xff08;本文中的源码来自JDK 8&#xff09;、使用场景进行举例&#xff0c…

数据可视化 信息可视化_可视化数据以帮助清理数据

数据可视化 信息可视化The role of a data scientists involves retrieving hidden relationships between massive amounts of structured or unstructured data in the aim to reach or adjust certain business criteria. In recent times this role’s importance has been…

VS2005 ASP.NET2.0安装项目的制作(包括数据库创建、站点创建、IIS属性修改、Web.Config文件修改)

站点&#xff1a; 如果新建默认的Web安装项目&#xff0c;那它将创建的默认网站下的一个虚拟应用程序目录而不是一个新的站点。故我们只有创建新的安装项目&#xff0c;而不是Web安装项目。然后通过安装类进行自定义操作&#xff0c;创建新站如下图&#xff1a; 2、创建新的安项…

docker的基本命令

docker的三大核心&#xff1a;仓库(repository),镜像(image),容器(container)三者相互转换。 1、镜像(image) 镜像&#xff1a;组成docker容器的基础.类似安装系统的镜像 docker pull tomcat 通过pull来下载tomcat docker push XXXX 通过push的方式发布镜像 2、容器(container)…

seaborn添加数据标签_常见Seaborn图的数据标签快速指南

seaborn添加数据标签In the course of my data exploration adventures, I find myself looking at such plots (below), which is great for observing trend but it makes it difficult to make out where and what each data point is.在进行数据探索的过程中&#xff0c;我…

使用python pandas dataframe学习数据分析

⚠️ Note — This post is a part of Learning data analysis with python series. If you haven’t read the first post, some of the content won’t make sense. Check it out here.Note️ 注意 -这篇文章是使用python系列学习数据分析的一部分。 如果您还没有阅读第一篇文…

实现TcpIp简单传送

private void timer1_Tick(object sender, EventArgs e) { IPAddress ipstr IPAddress.Parse("192.168.0.106"); TcpListener serverListener new TcpListener(ipstr,13);//创建TcpListener对象实例 ser…

SQLServer之函数简介

用户定义函数定义 与编程语言中的函数类似&#xff0c;SQL Server 用户定义函数是接受参数、执行操作&#xff08;例如复杂计算&#xff09;并将操作结果以值的形式返回的例程。 返回值可以是单个标量值或结果集。 用户定义函数准则 在函数中&#xff0c;将会区别处理导致语句被…

无向图g的邻接矩阵一定是_矩阵是图

无向图g的邻接矩阵一定是To study structure,tear away all flesh soonly the bone shows.要研究结构&#xff0c;请尽快撕掉骨头上所有的肉。 Linear algebra. Graph theory. If you are a data scientist, you have encountered both of these fields in your study or work …

移动pc常用Meta标签

移动常用 <meta charset"UTF-8"><title>{$configInfos[store_title]}</title><meta content"widthdevice-width,minimum-scale1.0,maximum-scale1.0,shrink-to-fitno,user-scalableno,minimal-ui" name"viewport"><m…

前端绘制绘制图表_绘制我的文学风景

前端绘制绘制图表Back when I was a kid, I used to read A LOT of books. Then, over the last couple of years, movies and TV series somehow stole the thunder, and with it, my attention. I did read a few odd books here and there, but not with the same ferocity …

Rapi

本页内容 ●引言●SMARTPHONE SDK API 库●管理设备中的目录文件●取系统信息●远程操作电话和短信功能 Windows Mobile日益成熟&#xff0c;开发者队伍也越来越壮大。作为一个10年的计算机热爱者和程序员&#xff0c;我也经受不住新技术的诱惑&#xff0c;倒腾起Mobile这个玩具…

android 字符串特殊字符转义

XML转义字符 以下为XML标志符的数字和字符串转义符 " ( 或 &quot;) ( 或 &apos;) & ( 或 &amp;) lt(<) (< 或 <) gt(>) (> 或 >) 如题&#xff1a; 比如&#xff1a;在string.xml中定义如下一个字符串&#xff0c;…

如何描绘一个vue的项目_描绘了一个被忽视的幽默来源

如何描绘一个vue的项目Source)来源 ) Data visualization is a great way to celebrate our favorite pieces of art as well as reveal connections and ideas that were previously invisible. More importantly, it’s a fun way to connect things we love — visualizing …