poj1733
Posted yijiull
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj1733相关的知识,希望对你有一定的参考价值。
题目连接:POJ - 1733
离散化+带权并查集
关于离散化:
比如本题,如果左端点不减1,那么如何表示某个点是不是一呢
比如这组输入5 5 0,表示5这个位置是一
但是你一开始初始化的时候rk[5]=0已经认为5这个位置是0了
所以我们用(l-1,r) 来表示对应的区间
如此一来初始化的零就不代表实际意义了
1 #include<algorithm> 2 #include<cstdio> 3 #include<cstring> 4 5 using namespace std; 6 const int maxn=200010; 7 int f[maxn],rk[maxn]; 8 int X[maxn]; 9 int l[maxn],r[maxn],d[maxn]; 10 char s[6]; 11 int n,m; 12 void init() 13 { 14 for(int i=0;i<maxn;i++) 15 { 16 f[i]=i; 17 rk[i]=0; 18 } 19 } 20 21 int gf(int x) 22 { 23 if(x!=f[x]) 24 { 25 int t=f[x]; 26 f[x]=gf(t); 27 rk[x]=(rk[x]+rk[t])%2; 28 } 29 return f[x]; 30 } 31 int BIN(int *a,int n,int x) 32 { 33 int l=0,r=n-1; 34 while(l<=r) 35 { 36 int m=(l+r)>>1; 37 if(a[m]==x) return m; 38 if(a[m]>x) r=m-1; 39 else l=m+1; 40 } 41 return -1; 42 } 43 int main() 44 { 45 while(scanf("%d%d",&n,&m)!=EOF) 46 { 47 init(); 48 int cnt=0; 49 int a,b; 50 for(int i=0;i<m;i++) 51 { 52 scanf("%d%d%s",&a,&b,s); 53 if(b<a) swap(a,b); 54 l[i]=a; 55 r[i]=b; 56 X[cnt++]=l[i]-1; 57 X[cnt++]=r[i]; 58 if(s[0]==‘e‘) d[i]=0; 59 else d[i]=1; 60 } 61 sort(X,X+cnt); 62 int ct=1; 63 for(int i=1;i<cnt;i++) if(X[i]!=X[i-1]) X[ct++]=X[i]; //去重 64 int ok=1,ans=m; 65 for(int i=0;i<m&&ok;i++) 66 { 67 int a=BIN(X,ct,l[i]-1); 68 int b=BIN(X,ct,r[i]); 69 int pa=gf(a); 70 int pb=gf(b); 71 if(pa!=pb) 72 { 73 f[pb]=pa; 74 rk[pb]=(rk[a]+d[i]-rk[b]+2)%2; 75 } 76 if(pa==pb&&(rk[a]+d[i])%2!=rk[b]) //此行忘记取模WA好久好久没发现错误。。。。 77 { 78 ok=0; 79 ans=i; 80 } 81 82 } 83 printf("%d\n",ans); 84 } 85 }
以上是关于poj1733的主要内容,如果未能解决你的问题,请参考以下文章