• POJ1182食物链 (并查集)


    第一反应就是和那个搞基的虫子的题很像(poj2492 http://www.cnblogs.com/wenruo/p/4658874.html),不过是把种类从2变成了3。

    错在很白痴的地方,卡了好久……

    代码:

    /*********************************************
    Problem: 1182		User: G_lory
    Memory: 972K		Time: 266MS
    Language: G++		Result: Accepted
    *********************************************/
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    
    const int N = 50005;
    
    int par[N];
    int rank[N];
    int rel[N];	// 0: same, 1: father eat son, 2: son eat father
    
    void init(int n)
    {
    	for (int i = 0; i <= n; ++i) {
    		par[i] = i;
    		rank[i] = 0;
    		rel[i] = 0;
    	}
    }
    
    int find(int x)
    {
    	if (par[x] == x) return x;
    	return find(par[x]);
    }
    
    // return 1 means root eat x, return 2 mean x eat root, return 0 mean same
    int rel_root(int x)
    {
    	int p, ans = 0;
    	for (p = x; p != par[p]; p = par[p]) {
    		ans = (ans + rel[p]) % 3;
    	}
    	return ans;
    }
    
    void unite(int x, int y, int c)
    {
    	int rootx = find(x);
    	int rooty = find(y);
    	if (rootx == rooty) return ;
    	int relx = rel_root(x);
    	int rely = rel_root(y);
    	if (rank[rootx] < rank[rooty]) {
    		par[rootx] = rooty;
    		rel[rootx] = ((rely - relx - c) % 3 + 3) % 3;
    	} else {
    		par[rooty] = rootx;
    		rel[rooty] = ((relx - rely + c) % 3 + 3) % 3;
    	}
    	if (rank[rootx] == rank[rooty]) ++rank[rootx];
    }
    
    bool same(int x, int y)
    {
    	return find(x) == find(y);
    }
    
    int main()
    {
        int n, k;
        int ch, x, y;
        scanf("%d%d", &n, &k);
    		int ans = 0;
    		init(n);
    		for (int i = 0; i < k; ++i) {
    			scanf("%d%d%d", &ch, &x, &y);
    			if (x > n || x <= 0 || y > n || y <= 0) {
    				++ans;
    				continue;
    			}
    			if (ch == 1) {
    				if (same(x, y)) {
    					if (rel_root(x) != rel_root(y)) ++ans;
    				} else unite(x, y, 0);
    			} else {
    				if (same(x, y)) { // x eat y
    					if ( !((rel_root(x) == 0 && rel_root(y) == 1) ||
    						   (rel_root(x) == 1 && rel_root(y) == 2) ||
    						   (rel_root(x) == 2 && rel_root(y) == 0)) )
    							++ans;
    				} else unite(x, y, 1);
    			}
    		}
    		printf("%d
    ", ans);
        return 0;
    }
    

      

    并查集模板:

    const int N = 300005;
    
    int par[N];		// father
    int rank[N];	// height
    
    void init(int n)
    {
    	for (int i = 0; i < n; ++i) {
    		par[i] = i;
    		rank[i] = 0;
    	}
    }
    
    int find(int x)
    {
    	if (par[x] == x) return x;
    	return par[x] = find(par[x]); // 压缩路径
    }
    
    void unite(int x, int y)
    {
    	x = find(x); y = find(y);
    	if (x == y) return ;
    	if (rank[x] < rank[y]) par[x] = y;
    	else par[y] = x;
    	if (rank[x] == rank[y]) ++rank[x];
    }
    
    bool same(int x, int y)
    {
    	return find(x) == find(y);
    }
    

      

  • 相关阅读:
    Jmeter_远程启动 I
    jmeter(九)逻辑控制器
    Mysql innodb 间隙锁 (转)
    MySQL- InnoDB锁机制
    Innodb间隙锁,细节讲解(转)
    性能测试:压测中TPS上不去的几种原因分析(就是思路要说清楚)
    Redis性能调优
    Redis基础
    VMThread占CPU高基本上是JVM在频繁GC导致,原因基本上是冰法下短时间内创建了大量对象堆积造成频繁GC。
    关于Hibernate二级缓存第三方插件EHCache缓存
  • 原文地址:https://www.cnblogs.com/wenruo/p/4720888.html
Copyright © 2020-2023  润新知