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 interconnection path between each pair of relays present in the network. Otherwise the network is disconnected. An empty network or a network with a single relay is considered connected. The safety factor f of a network with n relays is:
1. n, if the net remains connected regardless the number of relays removed from the net.

2. The minimal number of relays that disconnect the network when removed.

For example, consider the nets from figure 1, where the circles mark
the relays and the solid lines correspond to interconnection cables.
The network (a) is connected regardless the number of relays that are
removed and, according to rule (1), f=n=3. The network (b) is
disconnected when 0 relays are removed, hence f=0 by rule (2). The
network (c) is disconnected when the relays 1 and 2 or 1 and 3 are
removed. The safety factor is 2.

Input

Write
a program that reads several data sets from the standard input and
computes the safety factor for the cable networks encoded by the data
sets. Each data set starts with two integers: 0<=n<=50,the number
of relays in the net, and m, the number of cables in the net. Follow m
data pairs (u,v), u < v, where u and v are relay identifiers
(integers in the range 0..n-1). The pair (u,v) designates the cable that
interconnects the relays u and v. The pairs may occur in any
order.Except the (u,v) pairs, which do not contain white spaces, white
spaces can occur freely in input. Input data terminate with an end of
file and are correct.

Output

For
each data set, the program prints on the standard output, from the
beginning of a line, the safety factor of the encoded net.

Sample Input

0 0
1 0
3 3 (0,1) (0,2) (1,2)
2 0
5 7 (0,1) (0,2) (1,3) (1,2) (1,4) (2,3) (3,4)

Sample Output

0
1
3
0
2【分析】

图的连通度分为点连通度和边连通度:

(1)点连通度:只许删点,求至少要删掉几个点(当然,s和t不能删去,这里保证原图中至少有三个点);

(2)边连通度:只许删边,求至少要删掉几条边。

并且,有向图和无向图的连通度求法不同,因此还要分开考虑(对于混合图,只需将其中所有的无向边按照
无向图的办法处理、有向边按照有向图的办法处理即可)。

【1】有向图的边连通度:
这个其实就是最小割问题。以s为源点,t为汇点建立网络,原图中的每条边在网络中仍存在,容量为1,求该网络的最小割(也就是最大流)的值即为原图的边连通度。
【2】有向图的点连通度:
需要拆点。建立一个网络,原图中的每个点i在网络中拆成i‘与i‘‘,有一条边<i‘,
i‘‘>,容量为1 (<s‘, s‘‘>和<t‘, t‘‘>例外,容量为正无穷)。原图中的每条边<i,
j>在网络中为边<i‘‘, j‘>, 
容量为正无穷。以s‘为源点、t‘‘为汇点求最大流,最大流的值即为原图的点连通度。 
说明:最大流对应的是最小割。显然,容量为正无穷的边不可能通过最小割,也就是原图中的边和s、t两个点不能删去;若边<i, i‘‘>通过最小割,则表示将原图中的点i删去。
【3】无向图的边连通度:
将图中的每条边(i, j)拆成<i, j>和<j, i>两条边,再按照有向图的办法(【1】)处理;
【4】无向图的点连通度:
将图中的每条边(i, j)拆成<i, j>和<j, i>两条边,再按照有向图的办法(【2】)处理。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <queue>
#include <vector>
#define inf 0x7fffffff
#define met(a,b) memset(a,b,sizeof a)
typedef long long ll;
using namespace std;
const int N = 110;
const int M = 24005;
int n,m,cnt=0;
int toto;
struct man
{
    int u,v;
}mp[N*N];
struct Dinic {
    int s,t;
    struct Edge {
        int nxt,to,cap,flow;
    } edg[M];
    bool vv[N];
    bool vis[N];
    int d[N];
    int h[N];
    int cur[N];
    void init() {
        met(h,-1);toto=0;
    }
    void AddEdge(int x,int y,int z) {
        edg[toto].to=y;
        edg[toto].nxt=h[x];
        edg[toto].cap=z;edg[toto].flow=0;
        h[x]=toto++;
        edg[toto].to=x;edg[toto].flow=0;
        edg[toto].nxt=h[y];
        h[y]=toto++;
    }
    bool BFS() {
        memset(vis,0,sizeof(vis));met(d,-1);
        queue<int>q;
        q.push(s);
        d[s]=0;
        vis[s]=1;
        while (!q.empty()) {
            int x = q.front();
            q.pop();
            for (int i = h[x]; i!=-1; i=edg[i].nxt) {
                int v=edg[i].to;
                if (!vis[v] && edg[i].cap > edg[i].flow) {
                    vis[v]=1;
                    d[v] = d[x]+1;
                    q.push(v);
                }
            }
        }
        return vis[t];
    }

    int DFS(int x,int a) {
        if (x==t || a==0)
            return a;
        int flow = 0,f;
        for(int &i=cur[x]; i!=-1; i=edg[i].nxt) {
            int v=edg[i].to;
            if (d[x]+1 == d[v] && (f=DFS(v,min(a,edg[i].cap-edg[i].flow)))>0) {
                edg[i].flow+=f;
                edg[i^1].flow-=f;
                flow+=f;
                a-=f;
                if (a==0)
                    break;
            }
        }
        return flow;
    }

    int Maxflow(int s,int t) {
        this->s=s;
        this->t=t;
        int flow = 0;
        while (BFS()) {
            for(int i=0; i<=2*n; i++)cur[i]=h[i];
            flow+=DFS(s,inf);
        }
        return flow;
    }
} dc;
void Build()
{
    dc.init();
    for(int i=0;i<n;i++)dc.AddEdge(i,i+n,1);
    for(int i=0;i<m;i++){
        dc.AddEdge(mp[i].u+n,mp[i].v,inf);
        dc.AddEdge(mp[i].v+n,mp[i].u,inf);
    }
}
int main() {
    int u,v;
    while(~scanf("%d%d",&n,&m)){
        met(mp,0);int ans=inf;int pp[N][N];
        met(pp,0);
        for(int i=0;i<m;i++){
            scanf(" (%d,%d)",&u,&v);
            mp[i].u=u;mp[i].v=v;pp[u][v]=pp[v][u]=1;
        }
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                Build();
                if(!pp[i][j]){ans=min(ans,dc.Maxflow(i+n,j));if(ans==0)break;}
            }
            if(ans==0)break;
        }
        if(abs(ans)>=n)ans=n;
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-08-05 19:33:05

POJ 1966 Cable TV Network(顶点连通度的求解)的相关文章

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(无向图的顶点连通度)

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

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

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 【经典最小割问题】

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的边. 边权保证割

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<

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

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

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

POJ1966(Cable TV Network)

题目链接:传送门 题目大意:给你一副无向图,求解图的顶点连通度 题目思路:模板(图论算法理论,实现及应用 P396) Menger定理:无向图G的顶点连通度k(G)和顶点间最大独立轨数目之间存在如下关系: 1.若G是完全图,k(G)=|V(G)|-1 2.若G不是完全图,k(G)=min{P(A,B)}  其中A,B不直接相连 #include <iostream> #include <cstdio> #include <cstdlib> #include <cm