您的位置:首页 > 其它

[kuangbin带你飞]专题五 并查集 H POJ 1733

2016-10-17 12:25 253 查看
题目地址:https://vjudge.net/contest/66964#problem/H

思路:给一串01串,然后根据给出的条件,判断到第几个条件都是成立的。我把这题看做和之前D题的那题比较类似的。利用奇偶性质,更新祖先节点以及判断是否成立。这题有两个坑的地方,首先是更新值的时候要+2再%2防止出现负值,然后就是因为数据非常大所以要离散化,虽然点的最大值到达1e9但是一共只会有最多5000条记录,所以点的相对大小实际不会超过10000。

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=10000+10;
vector<int>v;
struct{
int u,v,w;
}E[maxn];
int fa[maxn];
int sum[maxn];
int l,m;

int find(int p)
{
if(p!=fa[p])
{
int pre=fa[p];
fa[p]=find(fa[p]);
sum[p]=(sum[p]+sum[pre]+2)%2;
}
return fa[p];
}

int getid(int x)
{
return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}

int main()
{
while(~scanf("%d",&l))
{
scanf("%d",&m);
v.clear();
for(int i=0;i<maxn;i++)
{
fa[i]=i;
sum[i]=0;
}
for(int i=0;i<m;i++)
{
char s[10];
scanf("%d%d%s",&E[i].u,&E[i].v,s);
if(s[0]=='e')
E[i].w=0;
else
E[i].w=1;
v.push_back(E[i].u);
v.push_back(E[i].v);
}
sort(v.begin(),v.end()),v.erase(unique(v.begin(),v.end()),v.end());
int ans=m;
for(int i=0;i<m;i++)
{
int p=getid(E[i].u);
int q=getid(E[i].v);
int s=E[i].w;
p--;
int fp=find(p);
int fq=find(q);
if(fp==fq)
{
if(s!=abs(sum[q]-sum[p]))
{
ans=i;
break;
}
}
else
{
fa[fq]=fp;
sum[fq]=(sum[p]+s-sum[q]+2)%2;
}
}
printf("%d\n",ans);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: