zoukankan      html  css  js  c++  java
  • poj1966 Cable TV Network

    拆点。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    using namespace std;
    int n, m, hea[2005], cnt, ss, tt, uu, vv, maxFlow, ans, lev[2005];
    const int oo=0x3f3f3f3f;
    bool w[205][205];
    queue<int> d;
    struct Edge{
    	int too, nxt, val;
    }edge[200005];
    int p(int x){
    	return x;
    }
    int q(int x){
    	return x+n;
    }
    void add_edge(int fro, int too, int val){
    	edge[cnt].nxt = hea[fro];
    	edge[cnt].too = too;
    	edge[cnt].val = val;
    	hea[fro] = cnt++;
    }
    void addEdge(int fro, int too, int val){
    	add_edge(fro, too, val);
    	add_edge(too, fro, 0);
    }
    bool bfs(){
    	memset(lev, 0, sizeof(lev));
    	lev[q(ss)] = 1;
    	d.push(q(ss));
    	while(!d.empty()){
    		int x=d.front();
    		d.pop();
    		if(x==p(ss) || x==q(tt))	continue;
    		for(int i=hea[x]; i!=-1; i=edge[i].nxt){
    			int t=edge[i].too;
    			if(!lev[t] && edge[i].val>0){
    				lev[t] = lev[x] + 1;
    				d.push(t);
    			}
    		}
    	}
    	lev[p(ss)] = lev[q(tt)] = 0;
    	return lev[p(tt)]!=0;
    }
    int dfs(int x, int lim){
    	if(x==p(tt))	return lim;
    	int addFlow=0;
    	for(int i=hea[x]; i!=-1 && addFlow<lim; i=edge[i].nxt){
    		int t=edge[i].too;
    		if(lev[t]==lev[x]+1 && edge[i].val>0){
    			int tmp=dfs(t, min(lim-addFlow, edge[i].val));
    			edge[i].val -= tmp;
    			edge[i^1].val += tmp;
    			addFlow += tmp;
    		}
    	}
    	return addFlow;
    }
    void dinic(){
    	maxFlow = 0;
    	while(bfs())	maxFlow += dfs(q(ss), oo);
    	ans = min(ans, maxFlow);
    }
    int main(){
    	while(scanf("%d %d", &n, &m)!=EOF){
    		memset(hea, -1, sizeof(hea));
    		memset(w, 0, sizeof(w));
    		cnt = 0;
    		for(int i=1; i<=m; i++){
    			scanf(" (%d,%d)", &uu, &vv);
    			uu++; vv++;
    			w[uu][vv] = w[vv][uu] = true;
    			addEdge(q(uu), p(vv), oo);
    			addEdge(q(vv), p(uu), oo);
    		}
    		for(int i=1; i<=n; i++)
    			addEdge(p(i), q(i), 1);
    		ans = oo;
    		bool flag=false;
    		for(int i=1; i<=n; i++)
    			for(int j=i+1; j<=n; j++)
    				if(!w[i][j]){
    					ss = i;
    					tt = j;
    					flag = true;
    					for(int k=1; k<=m; k++){
    						edge[2*k-2].val = oo;
    						edge[2*k-1].val = 0;
    					}
    					for(int k=2*m; k<cnt; k++){
    						if(k&1)	edge[k].val = 0;
    						else	edge[k].val = 1;
    					}
    					dinic();
    				}
    		if(!flag)	ans = min(ans, n);
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    接口和实现接口的类
    类的封装
    实验六:类的封装
    实验五:任意输入10个int类型数据,排序输出,再找出素数
    实验四:采用一维数组输出等腰三角形的杨辉三角
    2017-12-31 小组工作记录
    2017-12-30 小组工作记录
    2017-12-29 小组工作记录
    2017-12-24 小组工作记录
    2017-12-21 小组工作记录
  • 原文地址:https://www.cnblogs.com/poorpool/p/8745333.html
Copyright © 2011-2022 走看看