数据分割
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1300 Accepted Submission(s): 330
Problem Description
小w来到百度之星的赛场上,准备开始实现一个程序自动分析系统。
这个程序接受一些形如 xi=xj 或 xi≠xj 的相等/不等约束条件作为输入,判定是否可以通过给每个 w 赋适当的值,来满足这些条件。
输入包含多组数据。
然而粗心的小w不幸地把每组数据之间的分隔符删掉了。
他只知道每组数据都是不可满足的,且若把每组数据的最后一个约束条件去掉,则该组数据是可满足的。
请帮助他恢复这些分隔符。
这个程序接受一些形如 xi=xj 或 xi≠xj 的相等/不等约束条件作为输入,判定是否可以通过给每个 w 赋适当的值,来满足这些条件。
输入包含多组数据。
然而粗心的小w不幸地把每组数据之间的分隔符删掉了。
他只知道每组数据都是不可满足的,且若把每组数据的最后一个约束条件去掉,则该组数据是可满足的。
请帮助他恢复这些分隔符。
Input
第
1
行:一个数字
L
,表示后面输入的总行数。
之后 L 行,每行包含三个整数, i,j,e ,描述一个相等/不等的约束条件,若 e=1 ,则该约束条件为 xi=xj ,若 e=0 ,则该约束条件为 xi≠xj 。
i,j,L≤100000
xi,xj≤L
之后 L 行,每行包含三个整数, i,j,e ,描述一个相等/不等的约束条件,若 e=1 ,则该约束条件为 xi=xj ,若 e=0 ,则该约束条件为 xi≠xj 。
i,j,L≤100000
xi,xj≤L
Output
输出共
T+1
行。
第一行一个整数 T ,表示数据组数。
接下来 T 行的第 i 行,一个整数,表示第i组数据中的约束条件个数。
第一行一个整数 T ,表示数据组数。
接下来 T 行的第 i 行,一个整数,表示第i组数据中的约束条件个数。
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
Source
解题思路:二分每一个分割点(个人觉得这必然会超时,可能数据水了吧)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <set>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
#include <bitset>
#include <stack>
#include <queue>
#include <unordered_map>
#include <functional>
using namespace std;
int f[100009],n;
int a[100009],b[100009],c[100009];
vector<int>ans;
int Find(int k)
{
return f[k]==k?k:f[k]=Find(f[k]);
}
bool check(int k,int kk)
{
for(int i=0;i<=n;i++) f[i]=i;
for(int i=k;i<=kk;i++)
{
if(c[i])
{
int aa=Find(a[i]),bb=Find(b[i]);
if(f[aa]!=bb) f[aa]=bb;
}
}
for(int i=k;i<=kk;i++)
{
if(!c[i])
{
if(Find(a[i])==Find(b[i])) return 0;
}
}
return 1;
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++) scanf("%d%d%d",&a[i],&b[i],&c[i]);
ans.clear();
int pos=0;
while(pos!=n)
{
int l=pos+1,r=n,ans1=n;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(pos+1,mid)) l=mid+1;
else r=mid-1,ans1=mid;
}
ans.push_back(ans1-pos);
pos=ans1;
}
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++) printf("%d\n",ans[i]);
}
return 0;
}