poj 1966 无向图的点连通度

/********************************************************************
 ** @brief   图的连通度问题是指:在图中删去部分元素(点或边),使得图中指定的两个点s和t不连通
(不存在从s到t的路径),求至少要删去几个元素。
图的连通度分为点连通度和边连通度:
(1)点连通度:只许删点,求至少要删掉几个点(当然,s和t不能删去,这里保证原图中至少有三个点);
(2)边连通度:只许删边,求至少要删掉几条边。
并且,有向图和无向图的连通度求法不同,因此还要分开考虑(对于混合图,只需将其中所有的无向边按照
无向图的办法处理、有向边按照有向图的办法处理即可)。
【1】有向图的边连通度:
这个其实就是最小割问题。以s为源点,t为汇点建立网络,原图中的每条边在网络中仍存在,容量为1,
求该网络的最小割(也就是最大流)的值即为原图的边连通度。
【2】有向图的点连通度:
需要拆点。建立一个网络,原图中的每个点i在网络中拆成i'与i'',有一条边,容量为1
(例外,容量为正无穷)。原图中的每条边在网络中为边,
容量为正无穷。以s'为源点、t''为汇点求最大流,最大流的值即为原图的点连通度。
说明:最大流对应的是最小割。显然,容量为正无穷的边不可能通过最小割,也就是原图中的边和s、t两个点
不能删去;若边通过最小割,则表示将原图中的点i删去。
【3】无向图的边连通度:
将图中的每条边(i, j)拆成两条边,再按照有向图的办法(【1】)处理;
【4】无向图的点连通度:
将图中的每条边(i, j)拆成两条边,再按照有向图的办法(【2】)处理。
 ********************************************************************/
#include
#include
#include
#include
using namespace std;
#define MAX 105
#define INF 105
int map[MAX][MAX];
int N,M;
#define MAXN 105   
//#define INF 105   
#define MIN(x,y) (xq;
  int ans=0;
  memset(flow,0,sizeof(flow));
  while(true){//一直循环,直到不存在增广路径   
    while(!q.empty())q.pop();
    memset(f,-1,sizeof(f));
    f[s]=-2;//源点的父节点需特殊标示   
    min_flow[s]=INF;
    q.push(s);
    while(!q.empty()){//BFS寻找增广路径   
      int tmp=q.front();q.pop();
      for(int i=0;i=0){
          flow[f[k]][k]+=min_flow[t];//将新的流量加入flow
          flow[k][f[k]]=-flow[f[k]][k];
          k=f[k];
        }
        break;
      }
    }
    if(f[t]==-1)return ans;//不存在增广路径,返回   
    else ans+=min_flow[t];
  }
}
int main(int argc, char *argv[])
{
  while(scanf("%d%d",&n,&m)!=EOF){
    int a,b,ans;
    memset(map,0,sizeof(map));
    for(int i=0;i


你可能感兴趣的:(ACM)