• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
AC_Artist.zig_zag
然而我依然在补题、
博客园    首页    新随笔    联系   管理    订阅  订阅

bzoj 1016 最小生成树计数

    首先能发现一个规律,就是重构最小生成树的时候,一定不可能用一条权值较大的边和一条权值较小的边去替换他们中间的两条边。简而言之,就是只能权值相同的边相互替换。再进一步说,就是每种权值的边的数目是一定的。
  题目上说值相同的边最多10条,那么我们可以DFS选哪些,然后用并查集来判断是否成环。这里要注意,我们先kruskal把每种边选几条求出来,再按kruskal的顺序dfs每一种,每dfs一种,我们就要把这些边连起来(也就是边dfs边kruskal),这样可以确保求出每种边的组合是合法的。最后把它们乘起来就行了。
  看一些题解上说如果相同的边多了要用矩阵,表示不太懂......
minmst
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #define maxn 120
 6 #define maxm 1200
 7 #define ms 31011
 8 using namespace std;
 9 struct et
10 {
11         int s,t,val;
12 }e[maxm*2];
13 int f[maxm],v[maxm],c[maxm],l[maxm],r[maxm],q[maxm];
14 bool vis[maxm];
15 int n,m,tot,num,now,cnt;
16 long long sum[maxm],ans;
17 
18 int find(int i)
19 {
20         if (!f[i]) return i;
21         return find(f[i]);
22 }
23 
24 void dfs(int col,int k,int ll)
25 {
26         if (k>v[col]) {sum[col]++;return;}
27         for (int i=ll+1;i<=r[col];i++)
28         {
29                 int fx=find(e[i].s);
30                 int fy=find(e[i].t);
31                 if (fx!=fy) 
32                 {
33             int tmp=f[fx];
34                         f[fx]=e[i].t;
35                         dfs(col,k+1,i);
36                         f[fx]=tmp;
37                 }
38         }
39 }
40 
41 void add(int x,int y,int z)
42 {
43         e[++tot].s=x; e[tot].t=y; e[tot].val=z;
44 }
45 
46 bool cmp(et a,et b)
47 {
48         return a.val<b.val;
49 }
50 
51 int main()
52 {
53         int x,y,z;
54         scanf("%d %d",&n,&m);
55         for (int i=1;i<=m;i++)
56         {
57                 scanf("%d %d %d",&x,&y,&z);
58                 add(x,y,z);
59         }
60         sort(e+1,e+m+1,cmp);
61         int j=0;
62         for (int i=1;i<=m;i++)
63         {
64                 if (e[i].val!=e[i-1].val) num++,l[num]=i;
65                 r[num]=i,c[i]=num;
66         }//lisan
67         for (int i=1;i<=m;i++)
68         {
69                 int fx=find(e[i].s),fy=find(e[i].t);
70                 if (fx!=fy)
71                 {
72                         f[fx]=e[i].t;
73                         v[c[i]]++;
74                 }
75         }//kruskal
76         memset(f,0,sizeof(f));
77     now=0;
78         for (int i=1;i<=m;i++)
79         {
80         if (now!=c[i]) now=c[i],dfs(now,1,l[now]-1);
81                 int fx=find(e[i].s),fy=find(e[i].t);
82                 if (fx!=fy) f[fx]=e[i].t,cnt++;
83         }//dfs
84         if (cnt<n-1) ans=0; else ans=1;
85         for (int i=1;i<=num;i++) if  (sum[i]) ans*=sum[i],ans%=ms;
86         printf("%d\n",ans);
87         return 0;
88 }

 

AC without art, no better than WA !
posted @ 2013-03-19 22:53  Zig_zag  阅读(282)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3