zoukankan      html  css  js  c++  java
  • K

    题目:K - Electrification Plan

    题意:无向图,给n个点,n^2条边,每条边有个一权值,其中有k个点有发电站,给出这k个点的编号,选择最小权值的边,求使得剩下的点都能接收到电。

    思路:将所有待选边加入优先队列(priority_queue 优先队列),用并查集判断待选边是否符合要求,符合(即不在同一并查集中)则合并。

    代码:

    /***********************************************/
    ll n,k;
    int a[109];
    bool can[109];//此城市是否连通 
    ll c[109][109];
    int st[109];
    
    struct node{
    	int u,v;
    	int w;//边的权 
    };
    bool operator < (const node& a,const node& b)
    {//反过来,这样正好优先队列递增 
    	return a.w>b.w;
    }
    
    int find(int a)
    {
    	while(a!=st[a]) a=st[a];
    	return a;
    }
    
    void add(int a,int b)
    {
    	int fa=find(a);
    	int fb=find(b);
    	if(fa<fb) st[fb]=fa;
    	else st[fa]=fb;
    }
    
    void Kruskal()
    {
    	ll ans=0;
    	priority_queue<node>Q;
    	for(int i=1;i<=n;i++)
    	for(int j=1;j<=n;j++)
    		if(i!=j && find(i)!=find(j))
    		{
    			node t;
    			t.u=i; t.v=j; t.w=c[i][j];
    			Q.push(t);
    		}
    	while(!Q.empty())
    	{
    		node x=Q.top();
    		Q.pop();
    		if(find(x.u)!=find(x.v))
    		{
    			ans+=c[x.u][x.v];
    			add(x.u,x.v);
    		}
    	}
    	cout<<ans<<endl;
    }
    
    int main()
    {
    	std::ios::sync_with_stdio(false);
        std::cin.tie(0);
    	cin>>n>>k; 
    	for(int i=1;i<=n;i++) st[i]=i;
    	for(int i=1;i<=k;i++){
    		cin>>a[i];
    		can[a[i]]=1;
    		if(i>1){
    			add(a[i],a[i-1]); 
    		}
    	}
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++)
    			cin>>c[i][j];
    	}
    	Kruskal();
    	return 0;
    }
    

      

  • 相关阅读:
    java进阶(36)--IO和Properties联合使用(配置文件)
    java进阶(34)--File类、目录复制
    java进阶(33)--IO流
    java进阶(32)--Collections工具类
    java进阶(31)--TreeSet集合、TreeMap集合、自平衡二叉树
    解决Excel打开空白或慢的问题
    CCS
    CCS
    CCS
    CCS
  • 原文地址:https://www.cnblogs.com/liuyongliu/p/10346836.html
Copyright © 2011-2022 走看看