zoukankan      html  css  js  c++  java
  • luogu2762 太空飞行计划问题

    最大权闭合子图
    参考,胡伯涛论文。
    示意图
    10,8,6,3这个简单割对应的闭合子图是A1,B1,B2

    输出路径时,最后一次层次图中,与源点相连的点即选做的实验,与汇点相连的点即选用的仪器。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    using namespace std;
    int n, m, maxFlow, uu, vv, ss, tt, tot, cnt, hea[105], lev[105], fff;
    const int oo=0x3f3f3f3f;
    queue<int> d;
    struct Edge{
    	int too, nxt, val;
    }edge[20005];
    char aaa[100005];
    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));
    	d.push(ss);
    	lev[ss] = 1;
    	while(!d.empty()){
    		int x=d.front();
    		d.pop();
    		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);
    			}
    		}
    	}
    	return lev[tt]!=0;
    }
    int dfs(int x, int lim){
    	if(x==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(){
    	while(bfs())	maxFlow += dfs(ss, oo);
    }
    int main(){
    	memset(hea, -1, sizeof(hea));
    	cin>>n>>m;
    	ss = 0; tt = n + m + 1;
    	for(int i=1; i<=n; i++){
    		scanf("%d", &uu);
    		tot += uu;
    		addEdge(ss, i, uu);
    		fff = 0;
    		char ch=getchar();
    		memset(aaa, 0, sizeof(aaa));
    		while((ch>='0' && ch<='9') || ch==' ')
    			aaa[++fff] = ch, ch = getchar();
    		for(int j=1; j<=fff+1; j++){
    			if(aaa[j]>='0' && aaa[j]<='9')
    				vv = vv * 10 + aaa[j] - '0';
    			else{
    				vv += n;
    				if(vv>n)	addEdge(i, vv, oo);
    				vv = 0;
    			}
    		}
    	}
    	for(int i=1; i<=m; i++){
    		scanf("%d", &uu);
    		addEdge(n+i, tt, uu);
    	}
    	dinic();
    	tot -= maxFlow;
    	for(int i=1; i<=n; i++)
    		if(lev[i])	printf("%d ", i);
    	printf("
    ");
    	for(int i=n+1; i<=n+m; i++)
    		if(lev[i])	printf("%d ", i-n);
    	printf("
    ");
    	cout<<tot<<endl;
    	return 0;
    }
    
  • 相关阅读:
    现代软件工程 第一章 概论 第3题——韩婧
    现代软件工程 第一章 概论 第2题——韩婧
    小组成员邓琨、白文俊、张星星、韩婧
    UVa 10892 LCM的个数 (GCD和LCM 质因数分解)
    UVa 10780 幂和阶乘 求n!中某个因子的个数
    UVa 11859 除法游戏(Nim游戏,质因子)
    Codeforces 703C Chris and Road 二分、思考
    Codeforces 703D Mishka and Interesting sum 树状数组
    hdu 5795 A Simple Nim SG函数(多校)
    hdu 5793 A Boring Question 推公式(多校)
  • 原文地址:https://www.cnblogs.com/poorpool/p/8124044.html
Copyright © 2011-2022 走看看