zoukankan      html  css  js  c++  java
  • 【GOJ 1461】Liars and Truth Tellers

    题目

    正解

    这道题类似于 食物链,但比这道题简单。

    我们可以维护一个有 (2n) 个节点的并查集,理解时分成两个区间 ([1,n],[n+1,2n])。每个区间的对应值((i)(n+i))属于一种对立关系,一真一假,排好可能的正反两种情况。所以这两个数不能属于同一连通块

    接下来就很简单了。我们在它输入时同时进行处理、判断。当两个对应点属于同一个连通块时,那肯定不行,跳出。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int f[2005];
    int getf(int k) {
    	if(f[k]==k) {
    		return k;
    	}
    	return f[k]=getf(f[k]);
    }
    void merge(int u,int v) {
    	u=getf(u),v=getf(v);
    	if(u!=v) {
    		f[u]=v;
    	}
    }
    int main() {
    	int n,m;
    	scanf("%d %d",&n,&m);
    	for(int i=1; i<=n*2; i++) {
    		f[i]=i;
    	}
    	for(int k=1; k<=m; k++) {
    		int x,y;
    		char c[3];
    		scanf("%d %d %s",&x,&y,c);
    		if(!strcmp(c,"T")) {
    			merge(x,y),merge(x+n,y+n);
    		} else {
    			merge(x,y+n),merge(x+n,y);
    		}
    		for(int i=1; i<=n; i++) {
    			if(getf(i)==getf(i+n)) {
    				printf("%d",k-1);
    				return 0;
    			}
    		}
    	}
    	printf("%d",m);
    	return 0;
    }
    

    后记

    1. 如果代码一直有问题时,在很清楚的知道这道题的知识点、方向、思路正确的前提下,并且代码实现并不复杂,可以考虑重写代码,说不定有惊喜~

    2. 如果有相似模块需要更改后重新调用,在空间充裕的前提下可以采用命名空间(namespace)来规避名字污染、初始化不到位等情况。

    3. 如果要输入字符,建议以输入字符串的形式进行。

  • 相关阅读:
    循序渐进学习栈和队列
    循序渐进学习数据结构之线性表
    2018 noip 备战日志
    2018 noip 考前临死挣扎
    二维前缀和与差分
    noip模板复习
    宽搜总结
    强联通总结
    二分图再次总结
    NOIP 2016 换教室(期望dp)
  • 原文地址:https://www.cnblogs.com/Sam2007/p/13362359.html
Copyright © 2011-2022 走看看