Description
小 w 来到百度之星的赛场上,准备开始实现一个程序自动分析系统。
这个程序接受一些形如
输入包含多组数据。
然而粗心的小
他只知道每组数据都是不可满足的,且若把每组数据的最后一个约束条件去掉,则该组数据是可满足的。
请帮助他恢复这些分隔符。
Input
第
1
行:一个数字
之后L行,每行包含三个整数, i,j,e ,描述一个相等/不等的约束条件,若 e=1 ,则该约束条件为 xi=xj ,若 e=0 ,则该约束条件为 xi≠xj 。
i,j,L≤100000
xi,xj≤L
Output
输出共 T+1 行。
第一行一个整数 T ,表示数据组数。
接下来
Sample Input
6
2 2 1
2 2 1
1 1 1
3 1 1
1 3 1
1 3 0
Sample Output
1
6
Solution1
用并查集维护相等关系,用 set 维护不相等关系
x=y
时,看
x
的
x≠y
时,看并查集中
x
和
Code1
#include<cstdio>
#include<set>
#include<vector>
using namespace std;
namespace fastIO
{
#define BUF_SIZE 100000
//fread -> read
bool IOerror=0;
inline char nc()
{
static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
if(p1==pend)
{
p1=buf;
pend=buf+fread(buf,1,BUF_SIZE,stdin);
if(pend==p1)
{
IOerror=1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch)
{
return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';
}
inline void read(int &x)
{
char ch;
while(blank(ch=nc()));
if(IOerror)return;
for(x=ch-'0';(ch=nc())>='0'&&ch<='9';x=x*10+ch-'0');
}
#undef BUF_SIZE
};
using namespace fastIO;
#define maxn 100005
int fa[maxn];
int find(int x)
{
if(fa[x]==x)return x;
return fa[x]=find(fa[x]);
}
set<int>s[maxn],ss;
set<int>::iterator it;
void init()
{
for(it=ss.begin();it!=ss.end();it++)
fa[*it]=*it,s[*it].clear();
ss.clear();
}
vector<int>ans;
int main()
{
for(int i=1;i<=100000;i++)fa[i]=i;
int L,x,y,e,num=0;
read(L);
//scanf("%d",&L);
while(L--)
{
num++;
read(x),read(y),read(e);
//scanf("%d%d%d",&x,&y,&e);
x=find(x),y=find(y);
ss.insert(x),ss.insert(y);
if(e)
{
if(x==y)continue;
if(s[x].find(y)!=s[x].end())
{
ans.push_back(num);
num=0;
init();
}
else
{
for(it=s[x].begin();it!=s[x].end();it++)
{
s[y].insert(*it);
s[*it].insert(y);
s[*it].erase(x);
}
fa[x]=y;
}
}
else
{
if(x!=y)
{
s[x].insert(y);
s[y].insert(x);
}
else
{
ans.push_back(num);
num=0;
init();
}
}
}
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++)printf("%d\n",ans[i]);
return 0;
}
Solution2
并查集维护相等关系,倍增求每组数据的长度,先把限制中相等关系的用并查集合并,之后判断不相等关系是否在同一集合中
Code2
#include<cstdio>
#include<set>
#include<vector>
using namespace std;
namespace fastIO
{
#define BUF_SIZE 100000
//fread -> read
bool IOerror=0;
inline char nc()
{
static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
if(p1==pend)
{
p1=buf;
pend=buf+fread(buf,1,BUF_SIZE,stdin);
if(pend==p1)
{
IOerror=1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch)
{
return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';
}
inline void read(int &x)
{
char ch;
while(blank(ch=nc()));
if(IOerror)return;
for(x=ch-'0';(ch=nc())>='0'&&ch<='9';x=x*10+ch-'0');
}
#undef BUF_SIZE
};
using namespace fastIO;
#define maxn 100005
int n,x[maxn],y[maxn],e[maxn],fa[maxn];
int find(int x)
{
if(fa[x]==x)return x;
return fa[x]=find(fa[x]);
}
int unite(int x,int y)
{
x=find(x),y=find(y);
if(x!=y)fa[x]=y;
}
bool check(int l,int r)
{
if(r>n)return 0;
for(int i=l;i<=r;i++)
if(e[i])unite(x[i],y[i]);
for(int i=l;i<=r;i++)
if(!e[i]&&(find(x[i])==find(y[i])))
{
for(int j=l;j<=r;j++)fa[x[j]]=x[j],fa[y[j]]=y[j];
return 0;
}
return 1;
}
vector<int>ans;
int main()
{
read(n);
//scanf("%d",&n);
for(int i=0;i<=n;i++)fa[i]=i;
for(int i=1;i<=n;i++)read(x[i]),read(y[i]),read(e[i]);//scanf("%d%d%d",&x[i],&y[i],&e[i]);
for(int i=1;i<=n;)
{
int j=i,d=1;
while(check(i,j+d))
{
while(check(i,j+2*d))d<<=1;
j+=d;
d=1;
}
if(j+d<=n)ans.push_back(j+d-i+1);
i=j+d+1;
}
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++)printf("%d\n",ans[i]);
return 0;
}