poj 1966 Cable TV Network 无向图最小割

//poj 1966
//sep9
#include <iostream>
#include <queue>

using namespace std;
const int MAXN=512;
const int MAXM=20000;

struct Edge
{
	int v,nxt,f;
}e[MAXM],e_copy[MAXM];

queue<int> que;
int src,sink;
int g[MAXN],dist[MAXN];
int nume;
bool vis[MAXN];

const int MAX=1000000000;
int n,m,ans;

void addedge(int u,int v,int c)
{
    e[++nume].v=v;e[nume].f=c;e[nume].nxt=g[u];g[u]=nume;      
    e[++nume].v=u;e[nume].f=0;e[nume].nxt=g[v];g[v]=nume;  
}

void init()      
{      
    memset(g,0,sizeof(g));        
    nume=1;      
}      
      
int bfs()      
{      
    while(!que.empty()) que.pop();      
    memset(dist,0,sizeof(dist));      
    memset(vis,0,sizeof(vis));      
    vis[src]=true;      
    que.push(src);        
    while(!que.empty()){      
        int u=que.front();que.pop();      
        for(int i=g[u];i;i=e[i].nxt)      
            if(e[i].f>0&&!vis[e[i].v]){      
                que.push(e[i].v);      
                dist[e[i].v]=dist[u]+1;      
                vis[e[i].v]=true;       
                if(e[i].v==sink)      
                    return 1;      
            }      
    }      
    return 0;      
}  

int dfs(int u,int delta)      
{      
    if(u==sink)      
        return delta;      
    int ret=0;      
    for(int i=g[u];ret<delta&&i;i=e[i].nxt)      
        if(e[i].f>0&&dist[e[i].v]==dist[u]+1){      
            int dd=dfs(e[i].v,min(e[i].f,delta-ret));      
            if(dd>0){      
                e[i].f-=dd;      
                e[i^1].f+=dd;      
                ret+=dd;      
            }      
            else      
                dist[e[i].v]=-1;      
        }         
    return ret;      
}         

int dinic()      
{      
    int ret=0;      
    while(bfs()==1)      
        ret+=dfs(src,INT_MAX);      
    return ret;       
}   

int main()
{
	while(scanf("%d%d",&n,&m)==2){
		if(n==0) {puts("0");continue;}
		if(n==1) {puts("1");continue;}
		if(m==0) {puts("0");continue;}
		init();
		for(int i=0;i<n;++i)
			addedge(i,i+n,1);
		for(int i=0;i<m;++i){
			int u,v;
			while(getchar()!='(');
			scanf("%d,%d)",&u,&v);
			addedge(u+n,v,MAX);
			addedge(v+n,u,MAX);
		}
		for(int i=0;i<=nume;++i)
			e_copy[i]=e[i];
		ans=MAX;
		for(int i=1;i<n;++i){
			src=n,sink=i;
			for(int j=0;j<=nume;++j)
				e[j]=e_copy[j];
			ans=min(ans,dinic());
		}
		if(ans==MAX) ans=n;
		printf("%d\n",ans);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值