P - 食物链

Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u

Appoint description: 
System Crawler  (2015-01-27)

Description

动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。 
现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。 
有人用两种说法对这N个动物所构成的食物链关系进行描述: 
第一种说法是"1 X Y",表示X和Y是同类。 
第二种说法是"2 X Y",表示X吃Y。 
此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。 
1) 当前的话与前面的某些真的话冲突,就是假话; 
2) 当前的话中X或Y比N大,就是假话; 
3) 当前的话表示X吃X,就是假话。 
你的任务是根据给定的N(1 <= N <= 50,000)和K句话(0 <= K <= 100,000),输出假话的总数。 

Input

第一行是两个整数N和K,以一个空格分隔。 
以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。 
若D=1,则表示X和Y是同类。 
若D=2,则表示X吃Y。

Output

只有一个整数,表示假话的数目。

Sample Input

100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5

Sample Output

3

先吐槽一下关于多组样例的问题,闲话也不多说,这题网上大牛各种神奇的题解都有,第一份代码是常规带权并查集的做法,不多谈,我主要想谈一下第二份代码的思路。

如果我们换一个思路,把1--n看成与自身同类的集合,1+n--2*n看成自己吃的集合,1+2*n--3*n看成吃自己的集合,那么问题便简单多了~~~

 #include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<string> #define N 50005
#define M 105
#define mod 1000000007
//#define p 10000007
#define mod2 1000000000
#define ll long long
#define LL long long
#define eps 1e-6
#define inf 100000000
#define maxi(a,b) (a)>(b)? (a) : (b)
#define mini(a,b) (a)<(b)? (a) : (b) using namespace std; int n,m;
int f[N];
int r[N];
int ans; void ini()
{
ans=;
int i;
for(i=;i<=n;i++){
f[i]=i;
r[i]=;
}
} int find(int x)
{
int fa;
if(f[x]!=x)
{
fa=find(f[x]);
r[x]=(r[x]+r[ f[x] ])%;
f[x]=fa;
}
return f[x];
} void merge(int x,int y,int d)
{
int a,b;
a=find(x);
b=find(y);
if(a==b){
return;
}
f[b]=a;
r[b]=(-r[y]+r[x]+d)%;
} void solve()
{
int d,x,y;
int a,b;
int re;
int i;
for(i=;i<=m;i++){
scanf("%d%d%d",&d,&x,&y);
if(x>n || y>n){
ans++;continue;
}
if(d== && x==y){
ans++;continue;
}
a=find(x);
b=find(y);
re=(-r[x]+r[y])%;
if(a==b && re!=d-){
ans++;continue;
}
//printf(" i=%d\n",i);
merge(x,y,d-);
}
} void out()
{
printf("%d\n",ans);
} int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
//scanf("%d",&T);
//for(int ccnt=1;ccnt<=T;ccnt++)
//while(T--)
//while(scanf("%d%d",&n,&m)!=EOF)
scanf("%d%d",&n,&m);
{
ini();
solve();
out();
}
return ;
}

如果我们换一个思路,把1--n看成与自身同类的集合,1+n--2*n看成自己吃的集合,1+2*n--3*n看成吃自己的集合,那么问题便简单多了~~~

 #include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<string> #define N 50005
#define M 105
#define mod 1000000007
//#define p 10000007
#define mod2 1000000000
#define ll long long
#define LL long long
#define eps 1e-6
#define inf 100000000
#define maxi(a,b) (a)>(b)? (a) : (b)
#define mini(a,b) (a)<(b)? (a) : (b) using namespace std; int n,m;
int f[*N];
int ans; void ini()
{
ans=;
int i;
for(i=;i<=*n;i++){
f[i]=i;
}
} int find(int x)
{
int fa;
if(f[x]!=x)
{
fa=find(f[x]);
f[x]=fa;
}
return f[x];
} void merge(int x,int y)
{
int a,b;
a=find(x);
b=find(y);
if(a==b){
return;
}
f[b]=a;
} void solve()
{
int d,x,y;
int a,b;
int fx,sx;
int i;
for(i=;i<=m;i++){
scanf("%d%d%d",&d,&x,&y);
if(x>n || y>n){
ans++;continue;
}
if(d== && x==y){
ans++;continue;
}
a=find(x);
b=find(y);
fx=find(x+n);
sx=find(x+*n);
if(d==){
if(b==fx || b==sx){
ans++;continue;
}
else{
merge(x,y);
merge(x+n,y+n);
merge(x+*n,y+*n);
}
}
else{
if(b==a || b==sx){
ans++;continue;
}
else{
merge(x+n,y);
merge(x+*n,y+n);
merge(x,y+*n);
}
}
}
} void out()
{
printf("%d\n",ans);
} int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
//scanf("%d",&T);
//for(int ccnt=1;ccnt<=T;ccnt++)
//while(T--)
//while(scanf("%d%d",&n,&m)!=EOF)
scanf("%d%d",&n,&m);
{
ini();
solve();
out();
}
return ;
}

POJ 1182 食物链 [并查集 带权并查集 开拓思路]的更多相关文章

  1. poj 1182 食物链(高级的带权并查集)

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 76486   Accepted: 22742 Description ...

  2. 浅谈并查集&种类并查集&带权并查集

    并查集&种类并查集&带权并查集 前言: 因为是学习记录,所以知识讲解+例题推荐+练习题解都是放在一起的qvq 目录 并查集基础知识 并查集基础题目 种类并查集知识 种类并查集题目 并查 ...

  3. 【POJ 1984】Navigation Nightmare(带权并查集)

    Navigation Nightmare Description Farmer John's pastoral neighborhood has N farms (2 <= N <= 40 ...

  4. Poj1182 食物链(并查集/带权并查集)

    题面 Poj 题解 这里采用并查集的补集. \(x\)表示同类集合,\(x+n\)表示敌人集合,\(x+n\times2\)表示敌人的敌人集合. 如果当前给出的是一对同类关系,就判断\(x\)是否吃\ ...

  5. POJ 1984 Navigation Nightmare 【经典带权并查集】

    任意门:http://poj.org/problem?id=1984 Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K To ...

  6. [poj 2912] Rochambeau 解题报告 (带权并查集)

    题目链接:http://poj.org/problem?id=2912 题目: 题目大意: n个人进行m轮剪刀石头布游戏(0<n<=500,0<=m<=2000) 接下来m行形 ...

  7. poj 1733 Parity game【hash+带权并查集】

    hash一下然后用带权并查集做模2下的前缀和 #include<iostream> #include<cstdio> #include<map> #include& ...

  8. POJ 2492 A Bug's Life 带权并查集

    题意: 思路: mod2 意义下的带权并查集 如果两只虫子是异性恋,它们的距离应该是1. 如果两只虫子相恋且距离为零,则它们是同性恋. (出题人好猥琐啊) 注意: 不能输入一半就break出来.... ...

  9. POJ 2492 A Bug's Life (带权并查集 && 向量偏移)

    题意 : 给你 n 只虫且性别只有公母, 接下来给出 m 个关系, 这 m 个关系中都是代表这两只虫能够交配, 就是默认异性, 问你在给出的关系中有没有与异性交配这一事实相反的, 即同性之间给出了交配 ...

随机推荐

  1. HDOJ1195 双向BFS //单向也可以过 没想清

    #include<cstdio> #include<map> #include<vector> #include<stack> #include< ...

  2. js 判断是什么浏览器、是否为谷歌浏览器

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http ...

  3. OpenRead方法打开文件并读取

    实现效果: 知识运用: File类的OpenRead方法 //实现打开现有文件以进行读取 public static FileStream OpenRead(string path) FileStre ...

  4. PyCharm如何配置断点调试功能

    1. 点击菜单 PyCharm -> Preferences.. 2. 在左侧菜单栏找到Project:Django - > Project Interpreter 并点击配置 Proje ...

  5. Robotium实践之路源码创建测试项目

    1.JDK安装及环境配置 2.Eclipse安装 3.ADT插件安装 4.模拟器安装 5.准备源码 6.引进源码置项目中 .文件 .导入 .选择现有项目置工作空间中 .浏览 .选择项目,选择模拟器版本 ...

  6. SpringMVC+Spring+Mybatis整合程序之整合

    因为每个人思路不一样,所以我在这边先分享自己的思路对于mybatis开发持久层(DAO:DataBase Access Object 持久层访问对象)有两种.第一种:传统的开发持久层方式即需要程序员开 ...

  7. Xcode的Git管理

    在Xcode中创建工程的时候,我们很容易的可以将新创建的工程添加到Git中,如图: 但是如果是本地已经有的工程,那该如何添加到Git中呢? 首先终端进入到该工程的目录. 然后: git init gi ...

  8. iOS 静态库,动态库与 Framework

    iOS 静态库,动态库与 Framework     静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用. 什么时候我们会用到库呢 ...

  9. Codeforces Round #477滚粗记&&祭第一次div2场

    4.29 - 23:58:现在似乎在ST的样子……先等一波 Day4.29 prescript : 难得遇上一场9:00开始的div2,看了看大家都打,索性也当一回神仙吧. 晚上出去吃饭,匆匆赶回家, ...

  10. redis集群理解

    Redis在3.0中也引入了集群的概念,用于解决一些大数据量和高可用的问题,但是,为了达到高性能的目的,集群不是强一致性的,使用的是异步复制,在数据到主节点后,主节点返回成功,数据被异步地复制给从节点 ...