luogu4208
P4208 [JSOI2008]最小生成树计数
题目描述
现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)。由于不同的最小生成树可能很多,所以你只需要输出方案数对31011的模就可以了。
输入格式
第一行包含两个数,n和m,其中1<=n<=100; 1<=m<=1000; 表示该无向图的节点数和边数。每个节点用1~n的整数编号。
接下来的m行,每行包含两个整数:a, b, c,表示节点a, b之间的边的权值为c,其中1<=c<=1,000,000,000。
数据保证不会出现自回边和重边。注意:具有相同权值的边不会超过10条。
输出格式
输出不同的最小生成树有多少个。你只需要输出数量对31011的模就可以了。
输入输出样例
4 6
1 2 1
1 3 1
1 4 1
2 3 2
2 4 1
3 4 1
8
说明/提示
说明 1<=n<=100; 1<=m<=1000;1<=ci<=1e9
sol:相同权值的最小生成树有一个很玄学的特点就是相同边权的边的数量时固定的而且作用也是相同的,然后相同的边的方案数可以爆搜出来,只要注意一点就是搜方案数时的并查集不能路径压缩,否则回溯的时候回挂掉
#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
ll s=; bool f=; char ch=' ';
while(!isdigit(ch)) {f|=(ch=='-'); ch=getchar();}
while(isdigit(ch)) {s=(s<<)+(s<<)+(ch^); ch=getchar();}
return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
if(x<) {putchar('-'); x=-x;}
if(x<) {putchar(x+''); return;}
write(x/); putchar((x%)+'');
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=,M=,Mod=;
int n,m,fa[N],lian[N];
struct Edge
{
int u,v,w;
}E[M];
inline bool cmpw(Edge p,Edge q) {return p.w<q.w;}
inline int gf(int x){return (fa[x]==x)?x:fa[x]=gf(fa[x]);}
inline int gl(int x){return (lian[x]==x)?x:gl(lian[x]);}
inline int dfs(int now,int end,int cnt)
{
if(now==end+)
{
if(cnt==) return ;
return ;
}
int ans=dfs(now+,end,cnt);
int fx=gl(E[now].u),fy=gl(E[now].v);
if(fx!=fy)
{
lian[fx]=fy;
ans+=dfs(now+,end,cnt-);
lian[fx]=fx;
}
return ans;
}
int main()
{
int i,j,tot=;
R(n); R(m);
for(i=;i<=m;i++)
{
R(E[i].u); R(E[i].v); R(E[i].w);
}sort(E+,E+m+,cmpw);
for(i=;i<=n;i++) fa[i]=i;
int ans=;
for(i=;i<=m;)
{
for(j=;j<=n;j++) lian[j]=j;
int oo=i,now=tot;
while(i<=m&&E[i].w==E[oo].w)
{
E[i].u=gf(E[i].u); E[i].v=gf(E[i].v); i++;
}
for(j=oo;j<i;j++)
{
int fx=gf(E[j].u),fy=gf(E[j].v);
if(fx!=fy)
{
tot++; fa[fx]=fy;
}
}
ans=1LL*ans*dfs(oo,i-,tot-now)%Mod;
}
if(tot==n-) Wl(ans);
else puts("");
return ;
}
luogu4208的更多相关文章
- bzoj1016/luogu4208 最小生成树计数 (kruskal+暴搜)
由于有相同权值的边不超过10条的限制,所以可以暴搜 先做一遍kruskal,记录下来每个权值的边使用的数量(可以离散化一下) 可以证明,对于每个权值,所有的最小生成树中选择的数量是一样的.而且它们连成 ...
随机推荐
- eclipse 部署Tomcat 只有web-inf webapps没有项目文件
只有webapps 修改eclipse 默认的 发布位置改为 tomcat的安装位置 eclipse 默认的web-content 改为webroot ,发布后web-inf目录下才会有webroot ...
- ubuntu16.04环境下在docker上部署javaweb项目简单案例
因为一些原因,接触到了docker,经过一番研究,总算是有了一些自己的看法,有什么不对的地方,希望多多指教. 废话不多说,首先我这里使用的虚拟机安装的是ubuntu16.04版本,其他版本应该也可以. ...
- 关于微信小程序iOS端时间格式兼容问题
经过测试发现,当时间格式为 2018-08-08 08:00 ,需要将时间转为其他格式时,Android端转换成功,iOS端报错或是转为NaN 这是因为iOS端对符号‘ - ’不支持,也就是说iOS端 ...
- STM8 定时器
中断映射表 对应stm8_interrupt.c #pragma vector=1 __interrupt void TRAP_IRQHandler(void) { } #pragma vector= ...
- javascript 箭头函数的使用 初学者必看
为了保证可读性,本文采用意译而非直译.另外,本文版权归原作者所有,翻译仅用于学习. 本文我们介绍箭头(arrow)函数的优点. 更简洁的语法我们先来按常规语法定义函数: 1 2 3 4 5 funct ...
- MVC-区域(Area)
1.启用路由前的准备工作 1.Global.asax.cs中注册路由 public class MvcApplication : System.Web.HttpApplication { protec ...
- 前端面试记录NO.1
后端转前端,离职后第一次面试,技术面试的时候还是比较虚的,因为基础不是很扎实.主要问了工作中用过哪些技术,主流框架的区别,jQuery的掌握情况,Ajax的掌握情况,cookie的基本内容,还有浏览器 ...
- Python——格式化输出
如果我们需要格式化输出一个用户的信息,我们将会使用: ------------ info of xinbing ---------- Name : xinbing Age : 22 job : IT ...
- C++——异常处理
前言 大型和十分复杂的程序往往会产生一些很难查找的甚至是无法避免的运行时错误.当发生运行时错误时,不能简单地结束程序运行,而是退回到任务的起点,指出错误,并由用户决定下一步工作.面向对象的异常处理(e ...
- C++——友元 friend
人类社会的friend VS C++世界的friend 现实世界中,我们自己很多物品,朋友是可以使用的,但是陌生人就不行.那么money,朋友可以随便拿吗?这要是你和friend的关系深浅而定.人类社 ...