E. Split Into Two Sets
题目描述:
给定n对含有两个多米诺牌的数对,问能不能拆分成两套含有1-n的多米诺骨牌?
主要思路:
赛时觉得应该先转化成图,然后利用并查集来做,两套f数组,看看是不是能分成n/2堆?
然后就wa2了…
看了dalao的代码,才发现这是一道二分图染色的问题
#include<iostream>
#include<algorithm>
#include<vector>
#include<unordered_map>
using namespace std;
vector<int> a[200010];
unordered_map<int,int> book,num;
bool find(int x,int k)
{
if(!book[x])
book[x]=k;
else
{
if(book[x]==k) return 1;
else return 0;
}
for(int i=0;i<a[x].size();i++)
{
int now=a[x][i];
if(!find(now,3-k)) return 0;
}
return 1;
}
int main()
{
int t;
cin>>t;
while(t--)
{
book.clear();
num.clear();
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
num[x]+=1;
num[y]+=1;
a[x].push_back(y);
a[y].push_back(x);
}
bool flag=1;
for(int i=1;i<=n;i++)
{
if(!book[i])
{
if(!find(i,1))
{
flag=0;
}
}
if(num[i]!=2)
{
flag=0;
}
a[i].clear();
}
if(flag) cout<<"YES\n";
else cout<<"NO\n";
}
return 0;
}
F. Equate Multisets
题目描述:
给两个集合{a},{b},问能不能通过对b中的元素*2,/2来使a=b?
主要思路:
虽然题目上说不能对a进行操作,但是我们可以将是偶数的a/2 == (bx2=a)
所以,我们先将所有的是偶数的a/2变为奇数。
然后,就只需要对b考虑/2操作即可,无需再考虑x2,因为a里全是奇数,b*2一定为偶数。
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
unordered_map<int,int> book;
int a[200010],b[200010];
int main()
{
int t;
cin>>t;
while(t--)
{
book.clear();
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
while(a[i]%2==0&&a[i])
a[i]/=2;
book[a[i]]+=1;
}
for(int i=1;i<=n;i++)
{
cin>>b[i];
while(b[i]%2==0&&b[i])
b[i]/=2;
while(b[i])
{
if(book[b[i]])
{
book[b[i]]-=1;
break;
}
else b[i]/=2;
}
}
bool flag=1;
for(int i=1;i<=n;i++)
if(book[a[i]])
{
flag=0;
break;
}
if(flag) cout<<"YES\n";
else cout<<"NO\n";
}
return 0;
}
G. Passable Paths
题目描述:
给出一颗树,每次询问给出若干个点,要求这若干个点是否在同一条链上.
主要思路:
先找到深度最大的两个点为链的两个端点,然后利用lca判断其他点是否在链上。
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<cstring>
using namespace std;
const int N=2e5+10;
int n;
int depth[N];
int fa[N][30];
vector<int> l[N];
int a[N];
void bfs(int x)
{
memset(depth,0x3f,sizeof depth);
depth[1]=1;
depth[0]=0;
queue<int> q;
q.push(1);
while(q.size())
{
int now=q.front();
q.pop();
for(int i=0;i<l[now].size();i++)
{
int ne=l[now][i];
if(depth[ne]>depth[now]+1)
{
depth[ne]=depth[now]+1;
q.push(ne);
fa[ne][0]=now;
for(int k=1;k<=17;k++)
fa[ne][k]=fa[fa[ne][k-1]][k-1];
}
}
}
}
int lca(int x,int y)
{
if(depth[x]<depth[y]) swap(x,y);
// 处理到同一深度
for(int k=17;k>=0;k--)
{
if(depth[fa[x][k]]>=depth[y])
x=fa[x][k];
}
if(x==y) return x;
for(int k=17;k>=0;k--)
{
if(fa[x][k]!=fa[y][k])
{
x=fa[x][k];
y=fa[y][k];
}
}
return fa[x][0];
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<n;i++)
{
int x,y;
cin>>x>>y;
l[x].push_back(y);
l[y].push_back(x);
}
bfs(1);
int q;
cin>>q;
while(q--)
{
int m;
cin>>m;
for(int i=1;i<=m;i++) cin>>a[i];
int d1=0,d2=0;
for(int i=1;i<=m;i++)
{
if(depth[a[i]]>depth[d1])
d1=a[i];
}
for(int i=1;i<=m;i++)
{
if(depth[a[i]]>depth[d2]&&lca(d1,a[i])!=a[i])
d2=a[i];
}
bool flag=1;
int p=lca(d1,d2);
// cout<<d1<<' '<<d2<<' '<<p<<endl;
for(int i=1;i<=m;i++)
{
int now1=lca(d1,a[i]);
int now2=lca(d2,a[i]);
// cout<<now<<endl;
if(!(now1==a[i]&&now2==p||now1==p&&now2==a[i]))
{
flag=0;
break;
}
}
if(flag) cout<<"YES\n";
else cout<<"NO\n";
}
return 0;
}