zoukankan      html  css  js  c++  java
  • 编程算法

    食物链 并查集 代码(C)


    本文地址: http://blog.csdn.net/caroline_wendy


    题目: 有N仅仅动物, 分别编号为1,2,...,N. 全部动物都属于A,B,C中的一种. 已知A吃B, B吃C, C吃A.

    按顺序给出两种信息K条.

    第一种: x和y属于同一类.

    另外一种: x吃y. 

    信息之间可能会出错和矛盾, 求不对的信息数.


    比如:

    有N=10仅仅动物, 给定K=7条信息.

    (1) 1: x=101, y=1; 出错:没有101的动物.

    (2) 2: x=1, y=2; 动物1吃动物2.

    (3) 2: x=2, y=3; 动物2吃动物3.

    (4) 2: x=3, y=3; 出错, 动物3不能吃动物3.

    (5) 1: x=1, y=3; 出错, 动物1和动物3属于同一种, 与(2)(3)矛盾.

    (6) 2: x=3, y=1; 动物3吃动物1.

    (7) 1: x=5, y=5; 动物5和动物5属于同一种.

    result = 3, 即(1)(4)(5)出错.


    使用并查集(disjoint set)求解.

    创建3*N个元素的并查集.每一组表示元素i可能属于的种类x, 共3种.

    然后合并并查集. 找到矛盾信息.


    代码:

    /*
     * main.cpp
     *
     *  Created on: 2014.7.20
     *      Author: Spike
     */
    
    /*eclipse cdt, gcc 4.8.1*/
    
    #include <stdio.h>
    
    /*
     * main.cpp
     *
     *  Created on: 2014.7.20
     *      Author: spike
     */
    
    /*eclipse cdt, gcc 4.8.1*/
    
    #include <stdio.h>
    #include <memory.h>
    #include <limits.h>
    
    #include <algorithm>
    
    using namespace std;
    
    class DisjoinSet {
    	static const int MAX_N = 10000;
    	int par[MAX_N];
    	int rank[MAX_N];
    public:
    	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;
    		} 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[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);
    	}
    };
    
    class Program {
    	static const int MAX_N = 100;
    	int N = 100, K = 7;
    	int T[MAX_N] = {1,   2, 2, 2, 1, 2, 1},
    		X[MAX_N] = {101, 1, 2, 3, 1, 3, 4},
    		Y[MAX_N] = {1,   2, 3, 3, 3, 1, 4};
    	DisjoinSet DS;
    public:
    	void solve() {
    		DS.init(N*3);
    		int ans = 0;
    		for (int i=0; i<K; i++) {
    			int t = T[i];
    			int x = X[i]-1, y = Y[i]-1;
    
    			if (x<0 || N<=x || y<0 || N<=y) {
    				ans ++;
    				continue;
    			}
    
    			if (t==1) {
    				if (DS.same(x, y+N) || DS.same(x, y+2*N)) {
    					ans++;
    				} else {
    					DS.unite(x, y);
    					DS.unite(x+N, y+N);
    					DS.unite(x+N*2, y+N*2);
    				}
    			} else {
    				 if (DS.same(x,y) || DS.same(x, y+2*N)) {
    					 ans++;
    				 } else {
    					 DS.unite(x, y+N);
    					 DS.unite(x+N, y+2*N);
    					 DS.unite(x+2*N, y);
    				 }
    			}
    		}
    
    		printf("ans = %d
    ", ans);
    	}
    
    };
    
    int main(void)
    {
    	Program iP;
    	iP.solve();
    
    	return 0;
    }
    
    

    输出:

    ans = 3
    







  • 相关阅读:
    一文说清 InnoDB 的事务机制
    MySQL 索引结构
    Mysql索引(一篇就够le)
    对Elasticsearch生命周期的思考
    elasticsearch备份和还原(基于hdfs)
    想写一篇jvm的工具入门
    elasticsearch跨集群数据迁移
    [论文阅读]阿里DIN深度兴趣网络之总体解读
    [源码阅读] 阿里SOFA服务注册中心MetaServer(3)
    [源码阅读] 阿里SOFA服务注册中心MetaServer(2)
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/7255406.html
Copyright © 2011-2022 走看看