ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

POJ 1966 Cable TV Network

2021-02-11 16:32:42  阅读:183  来源: 互联网

标签:cnt ch TV 1966 cap rest int POJ include


题目链接: POJ 1966 Cable TV Network

题目大意:

一张 \(N\) 个点的无向图,求最少删去多少点后可以使得图不连通。

\(0\leq N\leq 50\)

思路:

这里有一个小技巧:点转边

将每个点拆成一个出点和一个入点,入点连接所有进边,出点连接所有出边,两点间连一条权值为 \(1\) 的边,代表删除这个点的代价,而连在原先点与点之间的边权值设为 \(\infty\),防止删除了真正的边。

然后这题就转化成最小割了,枚举源点 \(S\) 和汇点 \(T\) ,将最小割更新答案即可。

细节:

挺板子的,就是 \(S\) 和 \(T\) 不能是同一个点即可, \(S\) 是该点的出点, \(T\) 是另外那个点的入点。

Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<fstream>
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,b,a) for(int i=b;i>=a;i--)
#define N 105
#define M 5200
#define Inf 0x3f3f3f3f
using namespace std;
inline int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
    return s*w;
}
int head[N],to[M],nxt[M];
int cnt,s,t;
int val[M],cap[M],d[N];
bool conn[N][N];
queue<int> q;
void init(){mem(head,-1),cnt=-1,mem(conn,false);}
void add_e(int a,int b,int w){
    nxt[++cnt]=head[a],head[a]=cnt,to[cnt]=b;
    val[cnt]=cap[cnt]=w;
    if(w)add_e(b,a,0);
}
bool bfs(){
    mem(d,0);
    while(!q.empty())q.pop();
    d[s]=1,q.push(s);
    while(!q.empty()){
        int cur=q.front(); q.pop();
        for(int i=head[cur];~i;i=nxt[i]){
            if(cap[i]&&!d[to[i]]){
                d[to[i]]=d[cur]+1;
                q.push(to[i]);
                if(to[i]==t)return true;
            }
        }
    }
    return false;
}
int dinic(int x,int flow){
    if(x==t)return flow;
    int rest=flow,k;
    for(int i=head[x];(~i)&&rest;i=nxt[i]){
        if(cap[i]&&d[to[i]]==d[x]+1){
            k=dinic(to[i],min(cap[i],rest));
            if(!k)d[to[i]]=0;
            cap[i]-=k,cap[i^1]+=k;
            rest-=k;
        }
    }
    return flow-rest;
}
int main(){
    int n,m,a,b;
    while(cin>>n>>m){
        if(n==1){
            cout<<"1\n";
            continue;
        }
        init();
        rep(i,1,m){
            a=read(),b=read(),conn[a][b]=true;
            add_e(a+n,b,Inf),add_e(b+n,a,Inf);
        }
        rep(i,0,n-1)add_e(i,i+n,1);
        int ans=n;
        rep(i,0,n-1)rep(j,0,n-1){
            if(conn[i][j]||i==j)continue;
            rep(k,0,cnt)cap[k]=val[k];
            s=i+n,t=j;
            int maxflow=0,flow;
            while(bfs()){
                while(flow=dinic(s,Inf))maxflow+=flow;
            }
            ans=min(ans,maxflow);
        }
        cout<<ans<<endl;
    }
    return 0;
}

标签:cnt,ch,TV,1966,cap,rest,int,POJ,include
来源: https://www.cnblogs.com/Neal-lee/p/14397868.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有