UVA1660 Cable TV Network

求无向图的点连通分量,把一个点拆成一个入点和一个出点,之间连一条容量为1的有向边,表示能被用一次。最大流求最小割即可。

一些细节的东西:1.源点固定,汇点要枚举一遍,因为最小割割断以后会形成连通分量,在源点的那个连通分量里的割会更大。

2.每次枚举重建一下图。3.从入点进出点出就被认为是经过了一个原来的点,那么源点和汇点是不必经过的,所以一个在出点,另外一个枚举入点。

#include<bits/stdc++.h>
using namespace std;

const int maxn = 102;

struct Edge
{
    int v,cap,nxt;
};

vector<Edge> E;
vector<Edge> bak;
#define PB push_back

int head[maxn];

void AddEdge(int u,int v,int c)
{
    bak.PB({v,c,head[u]});
    head[u] = bak.size()-1;
    bak.PB({u,0,head[v]});
    head[v] = bak.size()-1;
}

int S,T,cur[maxn],d[maxn],q[maxn];

bool bfs()
{
    memset(d,0,sizeof(d));
    int l = 0, r = 0;
    q[r++] = S; d[S] = 1;
    while(r>l){
        int u = q[l++];
        for(int i = head[u]; ~i; i = E[i].nxt){
            Edge &e = E[i];
            if(!d[e.v] && e.cap>0){
                d[e.v] = d[u] + 1;
                q[r++] = e.v;
            }
        }
    }
    return d[T];
}

int dfs(int u,int a)
{
    if(u == T||!a) return a;
    int flow = 0,f;
    for(int &i = cur[u]; ~i; i = E[i].nxt){
        Edge &e = E[i];
        if(d[e.v] == d[u]+1 && (f = dfs(e.v,min(a,e.cap)))>0){
            flow += f; a -= f;
            e.cap -= f; E[i^1].cap += f;
            if(!a) break;
        }
    }
    return flow;
}

const int INF = 0x3f3f3f3f;

int MaxFlow()
{
    int flow = 0;
    while(bfs()){
        memcpy(cur,head,sizeof(head));
        flow += dfs(S,INF);
    }
    return flow;
}
int n,m;

void init()
{
    memset(head,-1,sizeof(head));
    bak.clear();
}

int main()
{
    //freopen("in.txt","r",stdin);
    while(~scanf("%d%d",&n,&m)){
        init();
        for(int i = 1; i < n; i++) AddEdge(i,i+n,1);
        for(int i = 0; i < m; i++){
            int u,v; scanf(" (%d,%d)",&u,&v);
            AddEdge(u+n,v,INF); AddEdge(v+n,u,INF);
        }
        int ans = n;
        S = n;
        for(T = 1; T < n; T++){
            E = bak;
            ans = min(ans,MaxFlow());
        }
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-11-08 22:18:25

UVA1660 Cable TV Network的相关文章

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 +

UVA-1660 Cable TV Network (最小割)

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

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

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

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

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

UVALIVE 3031 Cable TV Network

题意:求点联通度 首先看了别人的题解还是不晓得只枚举汇点的原因觉得行不通 关于求点联通度的建图方法 转自http://hi.baidu.com/lerroy312/item/5a5f36f2f5bba61bcf9f322e 点连通度的定义:一个具有N个点的图G中,在去掉任意k-1个顶点后(1<=k<=N),所得的子图仍然连通,去掉K个顶点后不连通,则称G是K连通图,K称作图G的连通度,记作K(G). 独立轨:A,B是图G(有向无向均可)的两个顶点,我们称为从A到B的两两无公共内顶的轨为独立轨,

UVA 1660 Cable TV Network

题意: 求一个无向图的点连通度. 分析: 把一个点拆成一个入点和一个出点,之间连一条容量为1的有向边,表示能被用一次.最大流求最小割即可.套模板就好 代码; #include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <queue>using namespace std;const int maxn=110;#define INF 1<