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,next;
};

node edges[N*10];
int head[N],e;
int curedge[N],h[N],num[N],pre[N];
int s,t;

void add(int u,int v,int cap)
{
    edges[e].v=v;
    edges[e].cap=cap;
    edges[e].next=head[u];
    head[u]=e++;
}

void Add(int u,int v,int cap)
{
    add(u,v,cap);
    add(v,u,0);
}

int Maxflow(int s,int t,int n)
{
    clr(h,0); clr(num,0);
    int i;
    FOR0(i,n+1) curedge[i]=head[i];
    int u=s,Min,k,x,ans=0;
    while(h[u]<n)
    {
        if(u==t)
        {
            Min=INF*100;
            for(i=s;i!=t;i=edges[curedge[i]].v)
            {
                x=curedge[i];
                if(edges[x].cap<Min)
                {
                    Min=edges[x].cap;
                    k=i;
                }
            }
            ans+=Min; u=k;
            for(i=s;i!=t;i=edges[curedge[i]].v)
            {
                x=curedge[i];
                edges[x].cap-=Min;
                edges[x^1].cap+=Min;
            }
        }
        for(i=curedge[u];i!=-1;i=edges[i].next)
        {
            if(edges[i].cap>0&&h[u]==h[edges[i].v]+1)
            {
                break;
            }
        }
        if(i!=-1)
        {
            curedge[u]=i;
            pre[edges[i].v]=u;
            u=edges[i].v;
        }
        else
        {
            if(--num[h[u]]==0) break;
            curedge[u]=head[u];
            x=n;
            for(i=head[u];i!=-1;i=edges[i].next)
            {
                k=edges[i].v;
                if(edges[i].cap>0&&h[k]<x) x=h[k];
            }
            h[u]=x+1; num[x+1]++;
            if(u!=s) u=pre[u];
        }
    }
    return ans;
}

int n,m;
int a[55][55];

int visit[55];

void DFS(int u)
{
    visit[u]=1;
    int i,v;
    FOR1(i,n) if(a[u][i]&&!visit[i])
    {
        DFS(i);
    }
}

int ok()
{
    clr(visit,0);
    DFS(1);
    int i;
    FOR1(i,n) if(!visit[i]) return 0;
    return 1;
}

int cal(int s,int t)
{
    clr(head,-1); e=0;
    int i,j;
    FOR1(i,n) Add(i,i+n,1);
    FOR1(i,n) for(j=1;j<=n;j++) if(a[i][j])
    {
        Add(i+n,j,INF);
    }

    return Maxflow(s+n,t,n+n+2);
}

int get()
{
    int x=0;
    char c=getchar();
    while(!isdigit(c))c=getchar();
    while(isdigit(c))
    {
        x=x*10+c-‘0‘;
        c=getchar();
    }
    return x;
}

int main()
{
    while(scanf("%d%d",&n,&m)!=-1)
    {
        if(m==0)
        {
            if(n==0) puts("0");
            else if(n==1) puts("1");
            else puts("0");
            continue;
        }
        clr(a,0);
        int u,v,i;
        FOR0(i,m)
        {
            u=get(); v=get();

            a[u+1][v+1]=a[v+1][u+1]=1;
        }

        if(!ok())
        {
            puts("0");
            continue;
        }
        int j;
        int ans=INF;
        FOR1(i,n) for(j=1;j<=n;j++) if(i!=j)
        {
            int x=cal(i,j);
            ans=min(ans,x);
        }
        if(ans==INF||ans==n-1) ans=n;
        PR(ans);
    }
}

ZOJ 2182 Cable TV Network(无向图点割-最大流),布布扣,bubuko.com

时间: 2025-01-11 16:00:25

ZOJ 2182 Cable TV Network(无向图点割-最大流)的相关文章

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<

poj1966Cable TV Network——无向图最小割(最大流)

题目:http://poj.org/problem?id=1966 把一个点拆成入点和出点,之间连一条边权为1的边,跑最大流即最小割: 原始的边权赋成inf防割: 枚举源点和汇点,直接相邻的两个点不必枚举: 注意:1.源点为枚举点i的出点,汇点为枚举点j的入点: 2.读入方式,免空格: 3.在dinic跑最大流的过程中,会改变边权,因此每次枚举都要复制一组边跑最大流,以免影响后面: 另:数据中的点从0开始,所以读入的时候++来使用. 代码如下: #include<iostream> #incl

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

UVA-1660 Cable TV Network (最小割)

题目大意:给一张n个点.m条边的无向图,求最小点割集的基数. 题目分析:求无向图最小点割集的基数可以变成求最小割.考虑单源s单汇t的无向图,如果要求一个最小点集,使得去掉这个点集后图不再连通(连通分量数目增多),只需将每个点拆成两个(入点和出点),并且之间连一条容量为1的弧,其他弧不变,在新网络上求最小割便得到这个最小点集的基数.但是本题无源无汇,可以指定一个点作为源点,枚举其它的点作为汇点,求得n-1个点集基数,取最小的便是答案.要注意每次枚举都要重新建图. 代码如下: # include<i

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

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

UVa1660 Cable TV Network (无向图,点连通度,最大流)

链接:http://bak3.vjudge.net/problem/UVA-1660 分析:这篇博客讲的很详细.http://www.cnblogs.com/xcw0754/p/4662429.html 1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 #include <vector> 5 using namespace std; 6 7 const int maxn = 100 +

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: 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

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