zoukankan      html  css  js  c++  java
  • Codeforces 1245D Shichikuji and Power Grid

    思路:

    这题一共有两种思路:
    1.设立一个虚点,将所有点和它连接,costci,然后其它点两两相连,cost为两点之间建立连接所需价格,然后求这个图的最小生成树,求出来的树中,和虚点相连的点就是自己设发电站的点,两个顶点都不是虚点的边就是需要修路的边;(在求解过程中需要使用long long
    2.由贪心思想可以得知,所有ci中最小的那个i点一定要设立发电站,此时我们遍历所有j>=1&&j<=n&&j!=i,这时j有两种选择:(1)和i相连 (2)自己建发电站;我们在这两种里面选择花费最小的那一种并更新cj,并记录更小的情况是自己建站还是和i连接(只是更新cj,还未决定到底是自己建or连接ior连接其它点),全部更新一遍之后,我们再在所有未建发电站的点里选取c最小的那一个,对它通电(是自己建站还是进行连接,就根据之前的记录),然后依次循环到所有点通电就ok了~(因为笔者只实现了最小生成树,这种贪心方法没有贴出代码,所以我就稍微啰嗦一点了QAQ)

    代码:

    #define IOS ios::sync_with_stdio(false);cin.tie(0)
    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int,int> P;
    typedef long long LL;
    #define fi first
    #define sc second
    #define pb(a) push_back(a)
    #define mp(a,b) make_pair(a,b)
    #define rp(i,n) for(int i=0;i<n;i++)
    #define rpn(i,n) for(int i=1;i<=n;i++)
    const int MAX_N=2000+99; 
    int par[MAX_N],rank_u[MAX_N];  //MAX_N集合里最多元素个数
    void init_union(int n){
    	for(int i=0;i<n;i++){
    		par[i]=i;
    		rank_u[i]=0;
    	}
    }
    int find(int x){
    	if(par[x]==x) return x;
    	else return par[x]=find(par[x]);
    }
    void unite(int x,int y){
    	x=find(x);
    	y=find(y);
    	if(x==y) return;
    	if(rank_u[x]<rank_u[y]) par[x]=y;
    	else{
    		par[y]=x;
    		if(rank_u[x]==rank_u[y]) rank_u[x]++;
    	}
    }
    bool same(int x,int y){
    	return find(x)==find(y);
    }
    struct edge{int u,v;LL cost;};
    bool cmp(const edge& e1,const edge& e2){
    	return e1.cost<e2.cost;
    }
    const int MAX_E=2001000+99;
    edge es[MAX_E];
    int V,E;//顶点数和边数
    vector<int> v1;//自己建发电站
    vector<P> v2;//连接别的发电站 
    LL kruskal(){
    	sort(es,es+E,cmp);
    	init_union(V);
    	LL res=0;
    	for(int i=0;i<E;i++){
    		edge e=es[i];
    		if(!same(e.u,e.v)){
    			if(e.u&&e.v) v2.pb(mp(e.u,e.v));
    			else v1.pb(e.u?e.u:e.v);
    			unite(e.u,e.v);
    			res+=e.cost;
    		}
    	}
    	return res;
    }
    P cod[MAX_N];
    LL K[MAX_N];
    LL cost(int a,int b){return (K[a]+K[b])*(abs(cod[a].fi-cod[b].fi)+abs(cod[a].sc-cod[b].sc));}
    int main(){
    	IOS;
    	int n;
    	cin>>n;
    	V=n+1; E=(n+1)*n/2;
    	rpn(i,n) cin>>cod[i].fi>>cod[i].sc;
    	int pos=0;
    	rpn(i,n){
    		LL cost;
    		cin>>cost;
    		es[pos++]=edge{0,i,cost};
    	}
    	rpn(i,n) cin>>K[i];
    	for(int i=1;i<n;i++){
    		for(int j=i+1;j<=n;j++) es[pos++]=edge{i,j,cost(i,j)};
    	}
    	cout<<kruskal()<<'
    ';
    	cout<<v1.size()<<'
    '<<v1[0];
    	for(int i=1;i<v1.size();i++) cout<<' '<<v1[i];
    	cout<<'
    '<<v2.size()<<'
    ';
    	rp(i,v2.size()) cout<<v2[i].fi<<' '<<v2[i].sc<<'
    ';
    	return 0;
    }
    
  • 相关阅读:
    C语言 realloc为什么要有返回值,realloc返回值具体解释/(解决随意长度字符串输入问题)。
    opencv中的vs框架中的Blob Tracking Tests的中文注释。
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
  • 原文地址:https://www.cnblogs.com/yuhan-blog/p/12308846.html
Copyright © 2011-2022 走看看