题目来源:https://www.luogu.org/problemnew/show/P1955
★当时怎么没有写出这题,我**了
相关知识:
unique函数的用法:例子:unique(g+1,g+m+1)-g
unique函数的作用就是去重(把重复的元素放在后面去)然后返回去重后(不考虑放在后面去的重复元素)的尾指针
lower_bound就是二分查找
思路:
关于等于或不等于,我们很容易想到把这些数 通过族群来区分,相等的就在一个族群(这就是并查集了)
但是你会发现这题数据特别大1e9了,单纯的并查集肯定不行了。
而这里的n却只有1e6,也就是说一共所给的x不会超过2e6,这里就要用到离散化了
然后单独的按题目的输入顺序来处理还是有点逻辑上的麻烦,我们不妨先把等于号的处理完,在处理不等于的(先把能并在一起的族群并在一起,而不等于就是用来判断OK不OK)
注意:
第二份代码中 m=unique(g+1,g+m+1)-g-1;
我要说明一下我为什么减1,(因为好多人都没减),如果你的g数组是从1开始记录的 那么就需要减1,从0开始记录就不用,我这里的m的意思是 g的有效长度
代码:
首先上一个容易理解的(VJ上过了7500ms,但洛谷严格一些TLE)
v1存储相等的情况,v2存储不相等的情况
map的作用就是并查集
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
#include<stack>
#include<queue>
#include<set>
using namespace std;
const int maxn=1e6+5;
const int mod=1e9+7;
typedef long long ll;
int n;
struct node
{
int a,b,is;
};
map<int , int > m;
inline void read(int &x)
{
char c;x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
int res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int seek(int k)
{
return k==m[k]?k:m[k]=seek(m[k]);
}
int main()
{
int t;read(t);
while(t--){
int n;read(n);
m.clear();
vector<node> v1,v2;
while(n--){
node t;read(t.a);read(t.b);read(t.is);
m[t.a]=t.a;
m[t.b]=t.b;
if(t.is==0) v2.push_back(t);
else v1.push_back(t);
}
for(int i=0;i<v1.size();i++){
int x=seek(v1[i].a);
int y=seek(v1[i].b);
if(x!=y) m[x]=y;
}
bool flag=1;
for(int i=0;i<v2.size();i++){
// int k=seek(v2[i].a);
// k=seek(v2[i].b);
if(m[seek(v2[i].a)]==m[seek(v2[i].b)]){
flag=0;
break;
}
}
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
然后这个是没有用map vector啥子之类的 写的,洛谷过了,用时(1800ms)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
#include<stack>
#include<queue>
#include<set>
using namespace std;
const int maxn=1e6+5;
const int mod=1e9+7;
typedef long long ll;
int n,m;
struct node
{
int a,b,is;
}f[maxn];
int g[maxn<<1],dad[maxn<<1];
inline void read(int &x)
{
char c;x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
int res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
bool cmp(node a,node b)
{
return a.is>b.is;
}
int seek(int k)
{
return k==dad[k]?k:dad[k]=seek(dad[k]);
}
int main()
{
int t;read(t);
while(t--){
int n;read(n);
m=0;
for(int i=1;i<=n;i++){
read(f[i].a);read(f[i].b);read(f[i].is);
g[++m]=f[i].a;
g[++m]=f[i].b;
}
sort(g+1,g+m+1);
m=unique(g+1,g+m+1)-g-1; //注意-1
for(int i=1;i<=m;i++) dad[i]=i;
for(int i=1;i<=n;i++){
f[i].a=lower_bound(g+1,g+m+1,f[i].a)-g;
f[i].b=lower_bound(g+1,g+m+1,f[i].b)-g;
}
sort(f+1,f+n+1,cmp);
bool flag=1;
for(int i=1;i<=n;i++){
int x=seek(f[i].a);
int y=seek(f[i].b);
if(f[i].is==1){
dad[x]=y;
}
else{
if(x==y){
flag=0;
break;
}
}
}
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}