poj1733 带权并查集+map

来源:互联网 发布:怎么下载word软件 编辑:程序博客网 时间:2024/05/16 14:35

开始看题目姿势不对,然后发现是n的长度是1000000000不是串的长度,又发现输出是最多符合前几项

这类区间并查集都维护一个权值终于感觉理解了,左区间需要-1

由于数组开不下,但询问只有5000条就可以用map存,hash不会。。。还是re因为初始化的时候不是FOR(i,1,n)是FOR(i,1,5000)

#include <iostream>#include<stdio.h>#include<cctype>#include<cstdlib>#include<math.h>#include<algorithm>#include<cstring>#include<string>#include<vector>#include<queue>#include<map>#include<set>#include<stack>using namespace std;#define mod 1000000007int f[5050];int v[5050];char x[10];int Find(int x){    if(x==f[x])return f[x];    int t=f[x];    f[x]=Find(f[x]);    v[x]=(v[x]+v[t])%2;    return f[x];}bool unionset(int a,int b,int x){    int aa=Find(a),bb=Find(b);    if(aa==bb)    {        if(v[a]-v[b]==x||v[b]-v[a]==x)            return true;        else return false;    }    f[bb]=aa;    v[bb]=(v[a]+x-v[b]+2)%2;    return true;}int main(){    int n,m;    map<int,int>mp;    while(scanf("%d%d",&n,&m)!=EOF)    {        int ans=0;        mp.clear();        for(int i=0;i<5010;i++)        {            f[i]=i;            v[i]=0;        }        int a,b,op;        int flag=0;        int cnt=0;        for(int i=1;i<=m;i++)        {            scanf("%d%d%s",&a,&b,x);            a--;            if(mp.find(a)==mp.end())            {                cnt++;                mp[a]=cnt;            }            if(mp.find(b)==mp.end())            {                cnt++;                mp[b]=cnt;            }            if(x[0]=='e')                op=0;            else op=1;            if(unionset(mp[a],mp[b],op)==false)                flag=1;            if(flag==0&&unionset(mp[a],mp[b],op)==true)                ans++;        }        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击