zoukankan      html  css  js  c++  java
  • 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);
    }
    

      

  • 相关阅读:
    HDU2059(龟兔赛跑)
    pat 1012 The Best Rank
    pat 1010 Radix
    pat 1007 Maximum Subsequence Sum
    pat 1005 Sign In and Sign Out
    pat 1005 Spell It Right
    pat 1004 Counting Leaves
    1003 Emergency
    第7章 输入/输出系统
    第六章 总线
  • 原文地址:https://www.cnblogs.com/wenruo/p/4720888.html
Copyright © 2011-2022 走看看