zoukankan      html  css  js  c++  java
  • UVa 1151 Buy or Build (最小生成树)

    题目链接

    先求出不买套餐的最小生成树的边

    然后枚举选择哪些套餐,将套餐中的边权置为 (0), 和原先最小生成树的边重新进行 (kruscal)

    而原先选不到的边,权值大于套餐和最小生成树的边,后来一定也选不到

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 1000100;
    const int INF = 1000000007;
    
    int T, n, q, cnt, ans;
    int c[10];
    int x[maxn], y[maxn];
    vector<int> Gc[10];
    
    struct Edge{
    	int u, v, w;
    	
    	bool operator < (const Edge& o) const{
    		return w < o.w;
    	}
    }e[maxn];
    
    vector<Edge> E, nE;
    
    int par[maxn], ran[maxn];
    
    int find(int x){
    	return par[x] == x ? x : par[x] = find(par[x]);
    }
    
    void unite(int x, int y){
    	x = find(x), y = find(y);
    	if(x == y) return;
    	
    	if(ran[x] < y){
    		par[x] = y;
    	} else{
    		par[y] = x;
    		if(ran[x] == ran[y]) ++ran[x];
    	}
    }
    
    void kruscal(){
    	for(int i = 1 ; i <= n ; ++i) par[i] = i, ran[i] = 1;
    	
    	int tot = 0;
    	for(int i = 1 ; i <= cnt ; ++i){
    		if(find(e[i].u) != find(e[i].v)){
    			unite(e[i].u, e[i].v);
    			++tot;
    			
    			E.push_back(e[i]);
    			if(tot == n - 1){
    				break;
    			}
    		}
    	}
    }
    
    int use[maxn];
    
    void dfs(int d){
    	if(d == q + 1){
    		nE.clear();
    		int res = 0;
    		
    		for(auto u : E){
    			nE.push_back(u);
    		}
    		
    		for(int i = 1 ; i <= q ; ++i){
    			if(use[i]){
    				res += c[i]; 
    				int u = -1;
    				for(auto v : Gc[i]){
    					Edge ne;
    					if(u != -1){
    						ne.u = u;
    						ne.v = v;
    						ne.w = 0;
    						nE.push_back(ne);
    						
    						u = v;
    					} else{
    						u = v;
    					}
    				}
    			}
    		}
    		
    		sort(nE.begin(), nE.end());
    		
    		for(int i = 1 ; i <= n ; ++i) par[i] = i, ran[i] = 1;
    		int tot = 0;
    		for(auto p : nE){
    			if(find(p.u) != find(p.v)){
    				unite(p.u, p.v);
    				++tot;
    				res += p.w;
    				
    				if(tot == n - 1){
    					ans = min(ans, res);
    					break;
    				}
    			}
    		} 
    		
    		return;
    	}
    	
    	use[d] = 1;
    	dfs(d + 1);
    	
    	use[d] = 0;
    	dfs(d + 1);
    } 
    
    ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
    
    int main(){
    	scanf("%d", &T);
    	int flag = 0;
    	while(T--){
    		if(flag){
    			printf("
    ");
    		}
    		flag = 1;
    		
    		cnt = 0;
    		for(int i = 1 ; i <= q ; ++i) Gc[i].clear();
    		E.clear(); 
    		memset(use, 0, sizeof(use));
    		ans = INF;
    		
    		scanf("%d%d", &n, &q);
    		for(int i = 1 ; i <= q ; ++i){
    			int u, v;
    			scanf("%d", &u);
    			scanf("%d", &c[i]);
    			for(int j = 1 ; j <= u ; ++j){
    				scanf("%d", &v);
    				Gc[i].push_back(v);
    			}
    		}
    		
    		for(int i = 1 ; i <= n ; ++i){
    			scanf("%d%d", &x[i], &y[i]);
    		}
    		
    		for(int i = 1 ; i <= n ; ++i){
    			for(int j = i + 1 ; j <= n ; ++j){
    				++cnt;
    				e[cnt].u = i, e[cnt].v = j;
    				e[cnt].w = (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]);
    			}
    		}
    		
    		sort(e + 1, e + 1 + cnt);
    		
    		kruscal();
    		
    		dfs(1); 
    		
    		printf("%d
    ", ans);
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    MyEclipse添加XML的xsd文件和dtd文件(自动补全xml节点代码)
    浅析Java中Map与HashMap,Hashtable,HashSet的区别(转载)
    jsp中:jsp声明与jsp脚本<%! int count=0;%> 与<% int count=0;%>
    JSP内置对象详细介绍(上)<转载>
    学习运用json
    win7与win7之间无法访问共享文件的问题解决(转)
    关于工作情绪化的问题
    Hadoop配置学习
    问题汇总
    mysql读写分离
  • 原文地址:https://www.cnblogs.com/tuchen/p/14987552.html
Copyright © 2011-2022 走看看