最小生成树计数(HYSBZ-1016)(简化版实现)
生活随笔
收集整理的這篇文章主要介紹了
最小生成树计数(HYSBZ-1016)(简化版实现)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Problem 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
思路:最小生成樹計數模版題
Source Program
#include<iostream> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #include<utility> #include<stack> #include<queue> #include<vector> #include<set> #include<map> #include<bitset> #define EPS 1e-9 #define PI acos(-1.0) #define INF 0x3f3f3f3f #define LL long long #define Pair pair<int,int> const int MOD = 31011; const int N = 1000+5; const int dx[] = {0,0,-1,1,-1,-1,1,1}; const int dy[] = {-1,1,0,0,-1,1,-1,1}; using namespace std;struct Edge {int x,y;int dis;bool operator < (const Edge &rhs)const{return dis<rhs.dis;} } edge[N]; struct build {int l,r;int cnt; } a[N]; int tot; int n,m; int father[N]; int sum;int Find(int x) {if(father[x]!=x)return Find(father[x]);return father[x]; }void dfs(int x,int now,int num) {if(now==a[x].r+1) {if(num==a[x].cnt)//選指定的條數sum++;return ;}int fx=Find(edge[now].x);int fy=Find(edge[now].y);if(fx!=fy) {//選father[fx]=fy;dfs(x,now+1,num+1);father[fx]=fx;father[fy]=fy;}dfs(x,now+1,num);//不選 }int Kruskal() {sort(edge+1,edge+m+1);for(int i=1; i<=n; i++)father[i]=i;int cnt=0;for(int i=1; i<=m; i++) {if(edge[i].dis!=edge[i-1].dis) {tot++;a[tot].l=i;a[tot-1].r=i-1;}int x=Find(edge[i].x);int y=Find(edge[i].y);if(x!=y) {father[y]=x;a[tot].cnt++;cnt++;}}a[tot].r=m;return cnt; }int main() {scanf("%d%d",&n,&m);int x,y,z;for(int i=1; i<=m; i++)scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].dis);int num=Kruskal();if(num!=n-1) {printf("0");return 0;}else{for(int i=1; i<=n; i++)father[i]=i;int res=1;for(int i=1; i<=tot; i++) {sum=0;dfs(i,a[i].l,0);res=res*sum%MOD;for(int j=a[i].l; j<=a[i].r; j++) {int x=Find(edge[j].x);int y=Find(edge[j].y);if(x!=y)father[y]=x;}}printf("%d",res);}return 0; }?
總結
以上是生活随笔為你收集整理的最小生成树计数(HYSBZ-1016)(简化版实现)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 青蛙的约会(POJ-1061)
- 下一篇: 2019 ICPC徐州站总结