hdu 5765 Bonds 状压


Bonds

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 424    Accepted Submission(s): 203


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
 
   
2 3 3 0 1 0 2 1 2 3 2 0 1 0 2
 

Sample Output
 
   
Case #1: 2 2 2 Case #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.
 

Author
FZU
 

Source
2016 Multi-University Training Contest 4
 

Recommend
wange2014   |   We have carefully selected several similar problems for you:   5792  5791  5790  5789  5788 
 

Statistic |  Submit |  Discuss |  Note


题意:给出一幅点数极少的图,问每条边在多少个极小割之内。


解:去掉任意一个极小割之后对应两个连通块

      对于任意一条边的答案,用所有极小割的数量减去这条边所在连通块的数量即可。



#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
#define mes(a,x,s)  memset(a,x,(s)*sizeof a[0])
#define mem(a,x)  memset(a,x,sizeof a)
#define ysk(x)  (1<<(x))
typedef long long ll;
typedef pair pii;
const int INF =0x3f3f3f3f;
const int maxn= 20   ;
const int maxm=200;
const int maxS=1048576;
int n,m,all,G[maxS+5],u[maxm+5],v[maxm+5],S,sum[maxS+5];
bool connected[maxS+3];



inline void add_edge(int ind,int x,int y)
{
       u[ind]=x,v[ind]=y;
       G[ysk(x)]|=ysk(y);
       G[ysk(y)]|=ysk(x);
}

int lowbit(int x)
{
    return x&(-x);
}

int main()
{
   std::ios::sync_with_stdio(false);
   int T,x,y,kase=0;cin>>T;
   while(T--)
   {
      cin>>n>>m;
      //得到邻接表(状压)
      memset(G,0,sizeof G);
      for0(i,m)
      {
          cin>>x>>y;
          add_edge(i,x,y);
      }

      //最大状态
      S=ysk(n)-1;
      //对于每个点集s,得到能够到达的点集G[s]
      for(int s=1;s<=S;s++)
      {
          int s2=s^lowbit(s);
          G[s]=G[s2]|G[lowbit(s)];

      }

      //判断点集s是否连通
      memset(connected,0,sizeof connected);
      queueq;
      for0(i,n) q.push(ysk(i) ),connected[ysk(i)]=1;
      while(!q.empty())
      {
          int x=q.front();q.pop();
          int s=G[x]&(~x);//点集x可到达的点集 ,不包括x自身
          while(s)
          {
              int s2=lowbit(s)|x;
              if(!connected[s2])
              {
                  connected[s2]=1;
                  q.push(s2);
              }
              s-=lowbit(s);
          }
      }


      //初始化
      all=0;
      memset(sum,0,sizeof sum);
      for1(s1,S-1)
      {
          int s2=S-s1;
          if(s1


你可能感兴趣的:(Training,ACM_图论,ACM_动态规划,状态压缩dp)