(1182)POJ

来源:互联网 发布:java十进制转字中文 编辑:程序博客网 时间:2024/05/19 08:23
#include<iostream>#include<cstdio>#include<string.h>#include<string>#include<stack>#include<set>#include<algorithm>#include<cmath>#include<vector>#include<map>#define ll __int64#define lll unsigned long long#define MAX 1000009#define eps 1e-8#define INF 0xfffffff#define mod 1000000007using namespace std;/*题型:并查集想法:这个应该是并查集的经典题目了,今天特地学一下。。看着飘过小妞的博客,一点一点来吧偏移量:number - 1x->y 偏移量0时 x和y同类x->y 偏移量1时 x被y吃x->y 偏移量2时 x吃y*/struct node{    int parent;     //p[i].parent表示节点i的父节点    int relation;   //p[i].relation表示节点i与其父节点(即p[i].parent)的关系} p[MAX];void init(int n){    int i;    for(i = 1; i<=n; i++)    {        p[i].parent = i;        p[i].relation = 0;        /*        0 代表跟父亲节点是同类        1 代表节点被当前根结点吃        2 代表节点吃当前根结点        */    }}int Find(int x){    int temp;    if(x==p[x].parent)    {        return x;    }    temp = p[x].parent;    p[x].parent = Find(temp);    p[x].relation = (p[x].relation + p[temp].relation) % 3;    //为什么这个公式是正确的呢?请看小牛的博客,用的是一种向量的思想··    //http://blog.csdn.net/niushuai666/article/details/6981689    return p[x].parent;}int main(){    int n,m;    int sum;    int a,b,number;    scanf("%d%d",&n,&m);    sum = 0;    init(n);    for(int i = 1; i<=m; i++)    {        scanf("%d%d%d",&number,&a,&b);        if(a>n||b>n)        {            sum++;            continue;        }        if(number==2&&a==b)        {            sum++;            continue;        }        int xx = Find(a);        int yy = Find(b);        if(xx!=yy)        {            p[yy].parent = xx;            p[yy].relation  = (p[a].relation + (number - 1) + 3 - p[b].relation)%3;            /*            关系域更新            当不属于一个集合时 rootx->rooty = rootx->x + x->y + y->rooty            x->y的偏移值为d-1            rootx->x的偏移量为 p[x].relation            y->rooty的偏移量为 3 - p[y].relation            */        }        else        {            if(number==1&&p[a].relation!=p[b].relation)            {                sum++;                continue;            }            if(number==2&&(3 - p[a].relation + p[b].relation)%3!=number-1)            {                sum++;                continue;            }            /*            关系域更新            当xx和yy属于同一集合是的时候            我们验证x->y之间的偏移量是否与题中给出的d-1一致            rootx = rooty            x->y = x->rootx + rooty->y            x->y = (3-relation[x]+relation[y])%3,            */        }    }    printf("%d\n",sum);    return 0;}
0 0
原创粉丝点击