很久以前做的题了
看到zhanghanchong神犇在做
有两个结论
最小生成树的两个性质:
1、边权相等的边的个数一定。
2、做完边权为w的所有边时,图的连通性相同。
有了这两个结论 每种权值 个数少可以爆搜
hzwer的代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mod 31011
using namespace std;
int n,m,cnt,tot,ans=1,sum;
int fa[105];
struct edge{int x,y,v;}e[1005];
struct data{int l,r,v;}a[1005];
inline int read()
{
int x=0;char ch=getchar();
while(ch<'0'||ch>'9'){ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x;
}
bool cmp(edge a,edge b){return a.v<b.v;}
int find(int x){return x==fa[x]?x:find(fa[x]);}
void dfs(int x,int now,int k)
{
if(now==a[x].r+1)
{
if(k==a[x].v)sum++;
return;
}
int p=find(e[now].x),q=find(e[now].y);
if(p!=q)
{
fa[p]=q;
dfs(x,now+1,k+1);
fa[p]=p;fa[q]=q;
}
dfs(x,now+1,k);
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)
fa[i]=i;
for(int i=1;i<=m;i++)
e[i].x=read(),e[i].y=read(),e[i].v=read();
sort(e+1,e+m+1,cmp);
for(int i=1;i<=m;i++)
{
if(e[i].v!=e[i-1].v){a[++cnt].l=i;a[cnt-1].r=i-1;}
int p=find(e[i].x),q=find(e[i].y);
if(p!=q){fa[p]=q;a[cnt].v++;tot++;}
}
a[cnt].r=m;
if(tot!=n-1){printf("0");return 0;}
for(int i=1;i<=n;i++)
fa[i]=i;
for(int i=1;i<=cnt;i++)
{
sum=0;
dfs(i,a[i].l,0);
ans=(ans*sum)%mod;
for(int j=a[i].l;j<=a[i].r;j++)
{
int p=find(e[j].x),q=find(e[j].y);
if(p!=q)fa[p]=q;
}
}
printf("%d",ans);
return 0;
}
而大了只能用吧啦吧啦定理了
很早的代码
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define M 31011
using namespace std;
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x)
{
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
struct data{
int l,r,tot;
}a[1005];
int cnt;
struct Edge{
int u,v,w;
bool operator < (const Edge &B) const{
return w<B.w;
}
}e[1005];
int n,m,tot,ans=1;
int fat[1005];
inline int getfat(int u)
{
return u==fat[u]?u:getfat(fat[u]);
}
inline void dfs(int x,int now,int k)
{
if (now==a[x].r+1)
{
if (k==a[x].tot) tot++;
return;
}
int fx=getfat(e[now].u),fy=getfat(e[now].v);
if (fx!=fy)
{
fat[fx]=fy;
dfs(x,now+1,k+1);
fat[fx]=fx; fat[fy]=fy;
}
dfs(x,now+1,k);
}
int main()
{
int fx,fy;
read(n); read(m);
for (int i=1;i<=m;i++)
read(e[i].u),read(e[i].v),read(e[i].w);
for (int i=1;i<=n;i++)
fat[i]=i;
sort(e+1,e+m+1);
for (int i=1;i<=m;i++)
{
if (e[i].w!=e[i-1].w) a[++cnt].l=i,a[cnt-1].r=i-1;
fx=getfat(e[i].u); fy=getfat(e[i].v);
if (fx!=fy)
{
fat[fx]=fy;
a[cnt].tot++; tot++;
}
}
a[cnt].r=m;
if (tot!=n-1) printf("0\n"),exit(0);
for (int i=1;i<=n;i++)
fat[i]=i;
for (int i=1;i<=cnt;i++)
{
tot=0;
dfs(i,a[i].l,0);
(ans*=tot)%=M;
for(int j=a[i].l;j<=a[i].r;j++)
{
fx=getfat(e[j].u),fy=getfat(e[j].v);
if(fx!=fy) fat[fx]=fy;
}
}
printf("%d\n",ans);
return 0;
}