POJ1733离散化(未很好解决)+并查集

来源:互联网 发布:c语言调用命令 编辑:程序博客网 时间:2024/05/16 12:30
解题思路:这题的思路和食物链的那题的思路差不多,就是利用了种类并查集,在一个种类里面维系的是节点和它的父亲节点之间的1的个数的奇偶性。处理的区间是(a-1,b].然后再利用并查集之前要对数据离散化,我离散化的方法是直接排序后在利用二分查找。这里肯定有好的离散化的方法,还有待解决。
  • Source Code
    #include<iostream>#include<stdio.h>#include<stdlib.h>#include<algorithm>#include<string.h>using namespace std;const int MAXSIZE = 10005;int tmp[MAXSIZE];typedef struct node{ int father; int relation;}Num;Num num[MAXSIZE];typedef struct Interval{ int l; int r; char par[5];}Inter;Inter inter[MAXSIZE];void init(int n){for(int i =1;i<=n;i++){ num[i].father = i; num[i].relation = 0;}}int find(int x){ if(num[x].father!=x){  int tmp = num[x].father;  num[x].father = find(num[x].father);  num[x].relation = (num[tmp].relation +num[x].relation)%2;  }  return num[x].father;}void Union(int p,int q,int a,int b,int v){ if(p>q){  num[p].father = q;  num[p].relation = (num[a].relation+num[b].relation+v)%2;}  else{  num[q].father = p;  num[q].relation = (num[a].relation+num[b].relation+v)%2;}}int BinaryLookUp(int l,int r,int value,int array[]){  while(l<=r){  int mid = (l+r)/2;  if(value>array[mid]){    l = mid+1;  }  else if(value == array[mid]){  return mid;  }  else{  r = mid-1;  }  }  return -1;}int main(){ int len,ansNum; scanf("%d%d",&len,&ansNum); init(2*ansNum); int cnt=1;  for(int i =1;i<=ansNum;i++){  scanf("%d%d%s",&inter[i].l,&inter[i].r,inter[i].par);  tmp[cnt++]=inter[i].l-1;  tmp[cnt++] =inter[i].r;  }  sort(tmp+1,tmp+cnt);  tmp[0] = -1;  int k = 1;  for(int i=1;i<cnt;i++){    if(tmp[i]!=tmp[i-1])      tmp[k++] = tmp[i];  }  //for(int i =1;i<k;i++) cout<<tmp[i]<<endl;  int ans = -1;  for(int i=1;i<=ansNum;i++){    int a = BinaryLookUp(1,k-1,inter[i].l-1,tmp);    int b = BinaryLookUp(1,k-1,inter[i].r,tmp);    int p = find(a);    int q = find(b);    if(p==q){     if(strcmp(inter[i].par,"even")==0){      if(num[a].relation!=num[b].relation){         ans = i-1;         break;        }     }     else{     if(num[a].relation == num[b].relation){     ans = i-1;     break;     }    }    }    else{    Union(p,q,a,b,(strcmp(inter[i].par,"even")==0?0:1));    }  }  if(ans == -1) cout<<ansNum<<endl;  else cout<<ans<<endl; return 0;}