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,记录下来每个权值的边使用的数量(可以离散化一下) 可以证明,对于每个权值,所有的最小生成树中选择的数量是一样的.而且它们连成 ...
随机推荐
- 怎样检测浏览器是否安装了某个插件, 比如flash
首先, 我们可以获取浏览器安装的所有在插件: navigator.plugins 它会返回一个类似数组的对象, 包含所有已安装插件的具体信息. navigator.plugins; 然后我们可以通过正 ...
- hdu 1045 要求全部逐一搜索完的深搜
#include<stdio.h> #include<string.h> int visit[10][10]; char map[10][10]; int n,ans,ss,t ...
- VMWare安装Ubuntu16.04
一 概述 VMware Workstation 12的安装(略过,自行百度) Ubuntu16.04的安装 克隆出多个镜像 二 Ubuntu16.04的安装 1 准备 Window10 专业版(关闭H ...
- mysql database和schema区别
在MySQL的语法操作中(MySQL5.0.2之后),可以使用CREATE DATABASE和CREATE SCHEMA来创建数据库,两者在功能上是一致的.在使用MySQL官方的MySQL管理工具My ...
- git 讲解
部署结构: - Git版本控制 - Git的使用 - 快速控制服务器代码版本 - 有利于团队协作 - 安装流程 现有代码 -> 编辑区 -> 寄存区 -> 版本库 1. 安装GIT ...
- CocoaPods - 发布自己的模块(公有库、私有库)
CocoaPods发布框架到远程公有库 1.编写代码~上传远程仓库 git init git add . git commit -m '提交到本地分支' //关联远程仓库 git remote add ...
- 在iframe内页触发顶层页面body的blur事件
//在iframe内页触发顶层页面body的blur事件. if (window != top) { $(document.body).click(function () { $(top.docume ...
- CSS之简介及引入方式
一.css的来源 1994年哈坤·利提出了CSS的最初建议.而当时伯特·波斯(Bert Bos)正在设计一个名为Argo的浏览器,于是他们决定一起设计CSS.其实当时在互联网界已经有过一些统一样式表语 ...
- Usages for IntelliJ & Eclipse
IntelliJ ⌘E Select a recently opened file from the list. ⌘/ (left command + /)⌥⌘/ (right command + / ...
- 再战css
1.盒模型的属性: 1.padding .box{ width: 200px; height: 200px; background-color: red; /*顺时针 上右下左*/ padding: ...