日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

BZOJ 1016--[JSOI2008]最小生成树计数(kruskal搜索)

發布時間:2023/12/10 javascript 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ 1016--[JSOI2008]最小生成树计数(kruskal搜索) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1016: [JSOI2008]最小生成樹計數

Time Limit:?1 Sec??Memory Limit:?162 MB
Submit:?7429??Solved:?3098
[Submit][Status][Discuss]

Description

  現在給出了一個簡單無向加權圖。你不滿足于求出這個圖的最小生成樹,而希望知道這個圖中有多少個不同的最小生成樹。(如果兩顆最小生成樹中至少有一條邊不同,則這兩個最小生成樹就是不同的)。由于不同的最小生成樹可能很多,所以你只需要輸出方案數對31011的模就可以了。

Input

  第一行包含兩個數,n和m,其中1<=n<=100; 1<=m<=1000; 表示該無向圖的節點數和邊數。每個節點用1~n的整數編號。接下來的m行,每行包含兩個整數:a, b, c,表示節點a, b之間的邊的權值為c,其中1<=c<=1,000,000,0
00。數據保證不會出現自回邊和重邊。注意:具有相同權值的邊不會超過10條。

Output

  輸出不同的最小生成樹有多少個。你只需要輸出數量對31011的模就可以了。

Sample Input

4 6
1 2 1
1 3 1
1 4 1
2 3 2
2 4 1
3 4 1

Sample Output

8

題目鏈接:

    http://www.lydsy.com/JudgeOnline/problem.php?id=1016?

Solution

  首先可以發現在不同的最小生成樹中,同權值的邊的數量是一樣的。。

  于是可以將每種權值的邊的貢獻分開算,然后用乘法原理就可以了。。

  對于某一種顏色,直接爆搜。。。感覺復雜度好像不太對。。。但是過了。。。

  算了反正都不知道多久之前寫的了。。。

代碼

#include<iostream> #include<cstdio> #include<algorithm> #define M 1010 #define mod 31011 using namespace std; int n,m,cnt,tot; int f[M],w[M],sum[M]; bool c[M]; struct edge{int l,r,w; }e[M],a[M]; bool cmp(edge p,edge q){return p.w<q.w;} int find(int x){if(f[x]==x) return f[x];return find(f[x]); } void RE(){for(int i=1;i<=n;i++) f[i]=i;} void dfs(int x,int now,int k){if(now==a[x].r+1){if(k==a[x].w)tot++;return;}int xx=find(e[now].l),yy=find(e[now].r);if(xx!=yy){f[xx]=yy;dfs(x,now+1,k+1);f[xx]=xx;f[yy]=yy;}dfs(x,now+1,k); } int main(){int ans=1;cnt=0;tot=0;int xx,yy;scanf("%d%d",&n,&m);for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].l,&e[i].r,&e[i].w);sort(e+1,e+1+m,cmp);RE();for(int i=1;i<=m;i++){if(e[i].w!=e[i-1].w){a[cnt].r=i-1;cnt++;a[cnt].l=i;}xx=find(e[i].l);yy=find(e[i].r);if(xx!=yy){f[xx]=yy;a[cnt].w++;tot++;}}a[cnt].r=m;if(tot+1!=n){printf("0\n");return 0;}RE();for(int i=1;i<=cnt;i++){tot=0;dfs(i,a[i].l,0);ans=(ans*tot)%mod;for(int j=a[i].l;j<=a[i].r;j++){xx=find(e[j].l);yy=find(e[j].r);if(xx!=yy) f[xx]=yy;}}printf("%d\n",ans);return 0; }

  

  

This passage is made by Iscream-2001.

?

轉載于:https://www.cnblogs.com/Yuigahama/p/9671568.html

總結

以上是生活随笔為你收集整理的BZOJ 1016--[JSOI2008]最小生成树计数(kruskal搜索)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。