zoukankan      html  css  js  c++  java
  • [USACO21OPEN] Portals G(Kruskal)

    [USACO21OPEN] Portals G

    解题思路

    这个题目不是很复杂。我们可以先以每个状态为一个点建图,若两个状态可以相互到达,就可以连一条边。我们的任务就是让这张图联通。

    容易发现,每个点的度都为 (2),结合题目,我们知道这张图一定是若干个不相交的环组成的。那么想要让这些换相交,我们就需要加一些边,也就是通过改变传送门顺序。

    比如说现在有一个点 (i)((i,p_2))((i,p_3)) 这两个点不连通,我们就需要改变一下顺序,将 ((i,p_2),(i,p_3)) 连起来,((i,p_1),(i,p_4)),那么两个环就连起来了。这个操作的花费是 (c_i) 块钱。

    因此,我们很容易想到 Kruskal,我们对所有 (c_i) 排序,然后查是否需要连这条边即可。

    时间复杂度 (O(nlog n))​。

    代码

    //Don't act like a loser.
    //This code is written by huayucaiji
    //You can only use the code for studying or finding mistakes
    //Or,you'll be punished by Sakyamuni!!!
    #include<bits/stdc++.h>
    using namespace std;
    
    int read() {
    	char ch=getchar();
    	int f=1,x=0;
    	while(ch<'0'||ch>'9') {
    		if(ch=='-')
    			f=-1;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9') {
    		x=x*10+ch-'0';
    		ch=getchar();
    	}
    	return f*x;
    }
    
    const int MAXN=1e5+10; 
    
    int n;
    int father[MAXN<<2],a[MAXN<<1][3],cnt[MAXN<<1];
    
    int node(int i,int j) {
    	return (i-1)*4+j;
    }
    int find(int x) {
    	if(father[x]!=x) {
    		father[x]=find(father[x]);
    	}
    	return father[x];
    }
    
    struct coin {
    	int val,id;
    }c[MAXN];
    bool cmp(coin a,coin b) {
    	return a.val<b.val;
    }
    
    signed main() {
    	cin>>n;
    	
    	for(int i=1;i<=n*4;i++) {
    		father[i]=i;
    	}
    	
    	for(int i=1;i<=n;i++) {
    		c[i].val=read();c[i].id=i;
    		for(int j=1;j<=4;j++) {
    			int x=read();
    			a[x][++cnt[x]]=node(i,j);
    		}
    		for(int j=1;j<=3;j+=2) {
    			int u=node(i,j),v=node(i,j+1);
    			u=find(u);v=find(v);
    			father[u]=v;
    		}
    	}
    	
    	for(int i=1;i<=2*n;i++) {
    		int u=a[i][2],v=a[i][1];
    		u=find(u);v=find(v);
    		father[u]=v;
    	}
    	
    	sort(c+1,c+n+1,cmp);
    	
    	int	ans=0;
    	for(int i=1;i<=n;i++) {
    		int u=node(c[i].id,1),v=node(c[i].id,3);
    		u=find(u);v=find(v);
    		if(u!=v) {
    			ans+=c[i].val;
    			father[u]=v;
    		}
    	}
    	
    	cout<<ans<<endl;
    	return 0;
    }
    
    
    
  • 相关阅读:
    【转】Quartz Cron 触发器 Cron Expression 的格式
    [转]MYSQL同时LEFT JOIN 多个表一例
    collapse用法
    flavor用法
    horny
    ever since用法
    be headed for用法
    Lemme用法
    scary用法
    feel like用法
  • 原文地址:https://www.cnblogs.com/huayucaiji/p/USACO21OPENPortals.html
Copyright © 2011-2022 走看看