poj 1733

这题离散化+并查集,没看出关dp什么事。(那他为什么放到dp里面)

用Si记录前i项的和。拆成两个点,i*2表示与第i个相同,i*2+1表示与第i个不同。用并查集判断。区间[a,b]就可以看成Sb-S(a-1),用并查集保存S的奇偶性的相同和相异情况。

注意数组开时要开成4*n+4,我在这里RE了一次

代码:

#include<cstdio>

#include<cstdlib>

#include<algorithm>

using namespace std;

 

struct dt{

         int id,p,l;

}a[10100];

int fa[20100];

bool d[5100],f;

bool cmp1(dt x,dt y){

         return x.p<y.p;

}

bool cmp2(dt x,dt y){

         return x.id<y.id;

}

int find(int x){

         return(fa[x]==x)?x:fa[x]=find(fa[x]);

}

void uni(int x,int y){

         int m1=find(x),n1=find(y);

//      for(int i=0;i<20;i++)printf("%d ",fa[i]);printf("\n");

//      printf("%d %d\n",m1,n1);

         if(abs(m1-n1)==1 && (m1+n1)%4==1){

                   f=1;

                   return;

         }

         fa[n1]=m1;

         return;

}

int main(){

         int n;

         scanf("%d",&n);

         scanf("%d",&n);

         for(int i=0;i<n*4+4;i++)

                   fa[i]=i;

         for(int i=0;i<n;i++){

                   int x,y;

                   char ch[20];

                   scanf("%d%d%s",&x,&y,ch);

                   a[i*2].id=i*2,a[i*2].p=x-1;

                   a[i*2+1].id=i*2+1,a[i*2+1].p=y-1;

                   if(ch[0]=='e')d[i]=0;else d[i]=1;

         }

         sort(a,a+n*2,cmp1);

         a[0].l=1;

         for(int i=1;i<n*2;i++)

                   if(a[i].p==a[i-1].p)

                            a[i].l=a[i-1].l;

                   else a[i].l=a[i-1].l+1;

         sort(a,a+n*2,cmp2);

         f=0;int ans=0;

         for(int i=0;i<n;i++){

                   int p=a[i*2].l-1,q=a[i*2+1].l;

//               printf("%d %d\n",p,q);

                   if(d[i]){

                            uni(p*2,q*2+1);

                            if(f)break;

                            uni(p*2+1,q*2);

                            if(f)break;

                   }else{

                            uni(p*2,q*2);

                            if(f)break;

                            uni(p*2+1,q*2+1);

                            if(f)break;

                   }

                   ans++;

         }

         printf("%d\n",ans);

         return 0;

}

posted @ 2013-07-07 15:21  shanquan2  阅读(202)  评论(0编辑  收藏  举报