Hdu 5765 Bonds(高维前缀和)
2016-10-24 21:02
246 查看
题意:
给一个n个点的无向连通图,求每条边被多少个极小割边集包括 (n<=20,m<=n*(n-1)/2)
思路:
极小边->分成两个联通块
1.先求出与每个状态相邻的点的状态集
2.bfs判断哪些点可以组成一个联通块
3.高维前缀和
给一个n个点的无向连通图,求每条边被多少个极小割边集包括 (n<=20,m<=n*(n-1)/2)
思路:
极小边->分成两个联通块
1.先求出与每个状态相邻的点的状态集
2.bfs判断哪些点可以组成一个联通块
3.高维前缀和
#include<bits/stdc++.h> using namespace std; const int N=21; int ans[1<<21],sta[1<<21],x[400],y[400]; bool flag[1<<21]; int q[1<<21]; int lowbit(int x){ return x&-x; } int main(){ int _,n,m,u,v; scanf("%d",&_); for(int Case=1;Case<=_;Case++){ scanf("%d%d",&n,&m); for(int i=0;i<(1<<n);i++) ans[i]=0,flag[i]=false,sta[i]=0; for(int i=0;i<m;i++){ scanf("%d%d",&u,&v); x[i]=u,y[i]=v; sta[1<<u]|=(1<<v),sta[1<<v]|=(1<<u); } //求出与每个状态相邻的点的状态集 for(int i=1;i<(1<<n);i++) sta[i]=sta[i-lowbit(i)]|sta[lowbit(i)]; int head=0,tail=0,Sta=(1<<n)-1; for(int i=0;i<n;i++) q[++tail]=(1<<i),flag[1<<i]=true; while(head<tail){ int num=q[++head]; //找出其它的点与num相连,而且不被包含在num中 int remain=sta[num]^(sta[num]&num); while(remain){ int x=lowbit(remain);//只包含一个1 if(!flag[num|x]) flag[num|x]=true,q[++tail]=num|x; remain-=lowbit(remain); } } int tot=0; for(int i=1;i<(1<<n);i++) if(flag[i]&&flag[Sta-i]) ans[Sta-i]++,ans[i]++,tot++; for(int i=0;i<n;i++) for(int j=(1<<n)-1;j>=0;j--) if(!(j>>i&1)) ans[j]+=ans[j^(1<<i)]; printf("Case #%d:",Case); for(int i=0;i<m;i++) printf(" %d",(tot-ans[(1<<x[i])|(1<<y[i])])/2); printf("\n"); } return 0; }
相关文章推荐
- HDU 5765 Bonds(bfs+高维前缀和)
- HDU - 5765 Bonds 高维前缀和
- HDU - 5765 状压dp + 高维前缀和
- hdu 5977 Garden of Eden(树分治+高维前缀和)
- Hdu 5765 Bonds
- 【HDU 5765】Bonds(进制运算妙用)
- HDU 5765 Bonds (二进制技巧)
- Hdu-5765 Bonds(状压)
- HDU 5765 Bonds(状压DP)
- HDU 5765 Bonds 巧妙状压暴力
- HDU 5765 Bonds
- HDU - 5977 Garden of Eden 【高维前缀和 + 点分治】
- HDU 5765 Bonds
- hdu 1081 最大子矩阵(二维前缀和优化)@
- hdu 5776 sum 前缀和
- HDU 2594 Simpsons’ HiddenTalents(KMP:后缀与前缀)
- (hdu step 5.2.2)统计难题(求一堆单词中以某一单词为前缀的单词的个数)
- hdu_1358Period(kmp找循环前缀)
- 多校第三场 1002 hdu 5317 RGCDQ (筛素数+前缀和)
- hdu 2594 Simpsons’ Hidden Talents (KMP求第一串前缀和第二串后缀最大值)