Food chains
Time Limit: 1000MS |
|
Memory Limit: 10000K |
Total Submissions: 66802 |
|
Accepted: 19713 |
There are three types of animal a,b,c in the Description animal kingdom, and the food chain of these three species is an interesting ring. A eat B, B eat c,c eat a.
Existing n animals, numbered with 1-n. Every animal is one of the a,b,c, but we don't know what it is.
Some people describe the food chain relationship between these n animals in two ways:
The first argument is "1 x y", which means that x and Y are homogeneous.
The second argument is "2 x y", which means x eats y.
This person to n animals, with the above two statements, a sentence after sentence to say K sentence, this k sentence some is true, some false. When one sentence satisfies one of the following three, the sentence is a lie, otherwise it is the truth.
1) The current words conflict with some of the preceding words, which is false;
2) The current word in x or y is greater than N, is a lie;
3) The current words say x eats x, is a lie.
Your task is to output the total number of falsehoods according to the given N (1 <= n <= 50,000) and the K-sentence (0 <= K <= 100,000).
The first line of Input is two integers n and K, separated by a space.
The following k lines each line is three positive integer d,x,y, and two numbers are separated by a space, where D denotes the kind of claim.
If d=1, it means that x and Y are homogeneous.
If d=2, it means x eats y.
Output has only one integer that represents the number of false lies.
Sample Input
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
There's a hole in the title. x<0| | x>=n| | y<0| | Y>=n to be counted as well.
With rank.
#include <stdio.h> #define MAX_N 200000 int par[max_n];
int Rank[max_n];
void init (int n) {for (int i=0;i<n;i++) par[i]=i,rank[i]=0;
} int find (int u) {return Par[u] = = u Par[u]: par[u] = find (Par[u]);
} 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);} int main () {int n,k,o,x,y;
scanf ("%d%d", &n,&k);
Init (n*3); int ans=0;
while (k--) {scanf ("%d%d%d", &o,&x,&y);
x--, y--; if (x<0| | x>=n| | y<0| |
y>=n) {ans++;
Continue } if (o==1) {if (Same (x,y+n) | | |
Same (x,y+n*2)) ans++;
else{Unite (x, y);
Unite (X+N,Y+N);
Unite (X+N*2,Y+N*2); }}else{if (Same (x, y) | |
Same (x,y+n*2)) ans++;
else{Unite (X,Y+N);
Unite (X+N,Y+N*2); Unite (X+n*2,y);
}}} printf ("%d\n", ans);
return 0; }
Not with rank.
#include <stdio.h>
#define MAX_N 160000
int par[max_n];
void init (int n) {for
(int i = 0; I <= n;i++) par[i]=i;
}
int find (int u) {
return par[u] = = u U:par[u] = find (Par[u]);
}
void unite (int x, int y) {
par[find (y)] = find (x);
}
BOOL Same (int x,int y) {
return find (x) ==find (y);
}
int main ()
{
int n,k,o,x,y;
scanf ("%d%d", &n,&k);
Init (n*3); int ans=0;
while (k--) {
scanf ("%d%d%d", &o,&x,&y);
x--, y--;
if (x<0| | x>=n| | y<0| | Y>=n) {
ans++;
Continue;
}
if (o==1) {
if (same (x,y+n) | | | Same (x,y+n*2)) ans++;
else{
Unite (x, y);
Unite (X+N,Y+N);
Unite (X+N*2,Y+N*2);
}
} else{
if (same (x, y) | | Same (x,y+n*2)) ans++;
else{
Unite (x,y+n);
Unite (X+N,Y+N*2);
Unite (x+n*2,y);
}}} printf ("%d\n", ans);
return 0;
}