javascript
BZOJ 1016--[JSOI2008]最小生成树计数(kruskal搜索)
1016: [JSOI2008]最小生成樹計數
Time Limit:?1 Sec??Memory Limit:?162 MBSubmit:?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 61 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搜索)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Red5 修改RTMP监听端口和ip
- 下一篇: JSP(Servlet)中从连接池获取连