Hdu-5765 Bonds(状压)

来源:互联网 发布:淘宝到家是干嘛的 编辑:程序博客网 时间:2024/06/05 18:15

Problem Description
Given an undirected connected graph with N points and M edges. ?? wants to know the number of occurrence in all bonds of graph for every edge.The index of points starts from 0.
An edge cut E of a Graph G is a set of edges of G and the G would be disconnected after deleting all the edges of E.
A bond of a graph is an edge cut does not have any other edge cut as a proper subset.


 

Input
The first line of the input gives the number of test cases T; T test cases follow.
Each test case consists of two integers: N, M, followed by M lines, each line contains two integers u, v, implying an undirected edge between u and v.

limits
T <= 20
2 <= N <= 20
N-1 <= M <= N*(N-1)/2
Edges are distinct.
No edge connects to the point itself.
N is larger than 10 in no more than 5 cases.
 

Output
For each test case output “Case #x: y1 y2 … yN” (without quotes), where x is the test case number (starting from 1), and yi is the occurrence times in all bonds of i-th edge.
 

Sample Input
23 30 10 21 23 20 10 2
 

Sample Output
Case #1: 2 2 2Case #2: 1 1
Hint
In first case, {(0,1),(0,2)} , {(0,1),(1,2)} , {(0,2),(1,2)} are bonds.In second case, {(0,1)},{(0,2)} is bond.
分析:点数很少,根据bonds的定义它一定是把原图分成两个联通块,那么我们枚举一下原图的连通子集个数除以二就是全图的bonds数量,然后对于每个询问,我们求一下不包含这条边两端的连通块数量再减去就行了。
#include<iostream>#include<string>#include<algorithm>#include<cstdlib>#include<cstdio>#include<set>#include<map>#include<vector>#include<cstring>#include<stack>#include<cmath>#include<queue>#define INF 0x3f3f3f3f#define eps 1e-9#define MAXN 10005using namespace std;int T,n,m;struct Edge{int u,v;}edge[500];int number[2000000],zy[22],e[22],cnt[2000000];int main(){for(int i = 1;i <= (1<<20)-1;i++) number[i] = number[i&(i-1)] + 1;for(int i = 0;i <= 20;i++) zy[i] = 1<<i;scanf("%d",&T);for(int t = 1;t <= T;t++){memset(e,0,sizeof(e));memset(cnt,0,sizeof(cnt));scanf("%d%d",&n,&m);for(int i = 1;i <= m;i++){int u,v;scanf("%d%d",&u,&v);edge[i].u = ++u;edge[i].v = ++v;e[u] += zy[v-1];e[v] += zy[u-1];}for(int i = 1;i <= zy[n] - 1;i++) if(number[i] == 1) cnt[i] = true; else  {for(int k = 1;k <= n;k++)     if((i & zy[k-1]) && cnt[i ^ zy[k-1]] && (e[k] & i) != 0)    {    cnt[i] = true;break; } } printf("Case #%d:",t);int tot = 0;for(int i = 1;i < zy[n]-1;i++)  if(cnt[i] && cnt[zy[n]-1-i]) tot++;for(int i = 1;i <= m;i++){int ans = 0,u = edge[i].u,v = edge[i].v;for(int j = zy[n]-1-zy[u-1]-zy[v-1];j;j = (zy[n]-1-zy[u-1]-zy[v-1])&(j-1)) if(cnt[j] && cnt[zy[n]-1-j]) ans++;printf(" %d",tot/2-ans);}printf("\n");}} 




0 0
原创粉丝点击