POJ 1966 ZOJ 2182 Cable TV Network

无向图顶点连通度的求解,即最少删除多少个点使无向图不连通。

我校“荣誉”出品的《图论算法理论、实现及其应用》这本书上写的有错误,请不要看了,正确的是这样的:

对于每个顶点,分成两个点,v和v’;

对于每个顶点,v到v’建边,容量为1;

对于无向边(u,v),建边<u’,v>和<v’,u>容量为+∞;

然后枚举每一对没有边直接相连的点对(x,y),x’为源点,y为汇点,跑最大流。最大流的最小值即为答案。

#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;

const int maxn=1000+10;
const int INF=99999999;

struct Edge
{
    int from,to,cap,flow;
};
vector<Edge>edges;
vector<int>G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];
int n,m,s,t;
int N,M;//N个节点,M条边
int LT[maxn][maxn];//判断两个点是否直接相连

//求出层次网络
bool BFS()
{
    memset(vis,0,sizeof(vis));
    queue<int>Q;
    Q.push(s);
    d[s]=0;
    vis[s]=1;
    while(!Q.empty())
    {
        int x=Q.front();
        Q.pop();
        for(int i=0; i<G[x].size(); i++)
        {
            Edge& e=edges[G[x][i]];
            if(!vis[e.to]&&e.cap>e.flow)
            {
                vis[e.to]=1;
                d[e.to]=d[x]+1;
                Q.push(e.to);
            }
        }
    }
    return vis[t];
}

//加边
void AddEdge(int from,int to,int cap)
{
    Edge r;
    r.from=from;
    r.to=to;
    r.cap=cap;
    r.flow=0;
    edges.push_back(r);
    Edge d;
    d.from=to;
    d.to=from;
    d.cap=0;
    d.flow=0;
    edges.push_back(d);
    m=edges.size();
    G[from].push_back(m-2);
    G[to].push_back(m-1);
}

//每个阶段来一次DFS增广
int DFS(int x,int a)
{
    if(x==t||a==0) return a;
    int flow=0,f;
    for(int i=cur[x]; i<G[x].size(); i++)
    {
        Edge& e=edges[G[x][i]];
        if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0)
        {
            e.flow+=f;
            edges[G[x][i]^1].flow-=f;
            flow+=f;
            a-=f;
            if(a==0) break;
        }
    }
    return flow;
}

//多个阶段,多次建立层次网络。
int Maxflow(int ss,int tt)
{
    int flow=0;
    while(BFS())
    {
        memset(cur,0,sizeof(cur));
        flow+=DFS(ss,INF);
    }
    return flow;
}

int main()
{
    while(~scanf("%d%d",&N,&M))
    {
        edges.clear();
        for(int i=0; i<maxn; i++) G[i].clear();
        memset(LT,0,sizeof(LT));
        for(int i=0; i<maxn; i++) LT[i][i]=1;

        for(int i=0; i<N; i++)
            AddEdge(i,i+N,1);

        while(M--)
        {
            int u,v;
            scanf(" (%d,%d)",&u,&v);
            AddEdge(u+N,v,INF);
            AddEdge(v+N,u,INF);
            LT[u][v]=LT[v][u]=1;//u和v直接相连
        }

        int ans=INF;
        for(int ii=N; ii<2*N; ii++)
        {
            for(int i=0; i<N; i++)
            {
                s=ii,t=i;
                if(!LT[s-N][t])//考虑原图中这两个点是否直接相连
                {
                    for(int j=0; j<edges.size(); j++)
                        edges[j].flow=0;

                    ans=min(Maxflow(s,t),ans);
                }
            }
        }
        if(ans>=INF) ans=N;
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-09-29 09:59:05

POJ 1966 ZOJ 2182 Cable TV Network的相关文章

ZOJ 2182 Cable TV Network(无向图点割-最大流)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2182 题意:给出一个无向图,问最少删掉多少个顶点之后图变得不连通? 思路:将原图每个点拆点(i,i+n),连边<i,i+n,1>,对原图的边(u,v),连边<u+n,v,INF>,<v+n,u,INF>.然后对于每对顶点(i,j)跑最大流(i+n,j).所有最大流的最小值即为答案. struct node { int v,cap,nex

POJ 1966 Cable TV Network(无向图的顶点连通度)

POJ 1966 Cable TV Network 链接:http://poj.org/problem?id=1966 题意:有线电视网络中,中继器的连接是双向的.如果网络中任何两个中继器之间至少有一条路,则中继器网络称为是连通的,否则中继器网络是不连通的.一个空的网络.以及只有一个中继器的网络被认为是连通的.具有n 个中继器的网络的安全系数f 被定义成: (1) f 为n,如果不管删除多少个中继器,剩下的网络仍然是连通的: (2) f 为删除最少的顶点数,使得剩下的网络不连通. 现在给定一个有

POJ 1966 Cable TV Network

Cable TV Network Time Limit: 1000ms Memory Limit: 30000KB This problem will be judged on PKU. Original ID: 196664-bit integer IO format: %lld      Java class name: Main The interconnection of the relays in a cable TV network is bi-directional. The ne

POJ 1966 Cable TV Network(顶点连通度的求解)

Cable TV Network Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 4678   Accepted: 2163 Description The interconnection of the relays in a cable TV network is bi-directional. The network is connected if there is at least one interconnecti

Cable TV Network 顶点连通度 (最大流算法)

Cable TV Network 题目抽象:给出含有n个点顶点的无向图,给出m条边.求定点联通度   K 算法:将每个顶点v拆成 v'   v''  ,v'-->v''的容量为1.           对于原图中的边(u,v)   连边   u''--->v'    v''-->u'.    求每对定点的P(u,v);以u为源点,v为汇点. 我们只需固定一个顶点,枚举其它汇点. 1 #include <iostream> 2 #include <cstdio> 3

POJ 1966:Cable TV Network(最小点割集)

http://poj.org/problem?id=1966 题意:给出一个由n个点,m条边组成的无向图.求最少去掉多少点才能使得图中存在两点,它们之间不连通. 思路:将点i拆成a和b,连一条a->b的容量为1的边,代表这个点只能走一次,然后如果点i和点j有边相连,那么将bi和aj相连,bj和ai相连,容量为INF,代表这条边可以走INF次. 然后O(n^2)枚举源点和汇点跑最大流,算的最小的最大流就是答案.(这个时候的最大流代表的是S跑到T需要经过多少路径(最小割),如果得到的最大流是INF,

poj 1966 Cable TV Network 顶点连通度

题目链接 给一个图, n个点m条边, 求至少去掉多少个点可以使得图不再联通.随便指定一个点为源点, 枚举其他点为汇点的情况, 跑网络流, 求其中最小的情况. 如果最后ans为inf, 说明是一个完全图, 那么结果就为n. 1 #include <iostream> 2 #include <vector> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #inclu

POJ 1966 Cable TV Network 【经典最小割问题】

Description n个点的无向图,问最少删掉几个点,使得图不连通 n<=50 m也许可以到完全图? Solution 最少,割点,不连通,可以想到最小割. 发现,图不连通,必然存在两个点不连通. 枚举源点汇点,要让源点汇点不连通.源点汇点不能割掉 网络建图: 为了割的是边,所以要点转化成边. 对于每个x,建立x'=x+n,对于不是S.T的点(因为S.T不能割掉),x向x'连一条边权为1的边 对于原图的边e(x,y) x'->y 连接inf的边,y'->x连接inf的边. 边权保证割

POJ1966.Cable TV Network——无向图的点连通度

http://poj.org/problem?id=1966 题目描述: 有线电视网络中,中继器的连接是双向的.如果网络中任何两个中继器之间至少有一条路,则中继器网络称为是连通的,否则中继器网络是不连通的.一个空的网络.以及只有一个中继器的网络被认为是连通的.具有n 个中继器的网络的安全系数f 被定义成: (1) f 为n,如果不管删除多少个中继器,剩下的网络仍然是连通的: (2) f 为删除最少的顶点数,使得剩下的网络不连通. 分析: 本题中的安全系数f 实际上就是无向图的顶点连通度κ(G).