QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#618110 | #1869. Power Station of Art | pzjQWQ | WA | 466ms | 59048kb | C++14 | 3.2kb | 2024-10-06 18:51:07 | 2024-10-06 18:51:08 |
Judging History
answer
/*
不补题的报应啊
为了符合交换的形式,我们把二操作转化为:
交换之后取反
考虑 a->b->c 操作之后会变成什么:
我们从 a[a],a[b],a[c] 和 c[a],c[b],c[c] 中变成了 a[c],a[b],a[a] 和 c[c],c[b],c[a]
也就是说,两个距离为 2 的点之间能随意交换信息
对每个连通块分别考虑,讨论它们是不是二分图
- 不是二分图:
那么一定有奇环,发现图上任意两点都能直接交换
那么把这些提出来然后比较信息是否全部相同
因为可以取反交换,所以只关注 first 而不关注 second
草了,你需要让需要改的个数恰好是偶数个
- 是二分图:
同一部之间可以互相交换
所以情况就有同一部之间交换消除,不同部之间最后再来交换
只需要判对面部交换后和需求的相同的加上自己部和需求相同的数量是否等于该需求的数量加上对面交换后需求的数量
*/
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
const int N=1e6+5;
int T,n,m,col[N];
bool flag,vis[N];
vector<int> G[N];
pair<int,int> a[N],b[N];
map<int,bool> flg;
map<pair<int,int>,int> cnt[4],mp[2];
pair<int,int> upd(pair<int,int> a){ return make_pair(a.first,1-a.second); }
void color(int u){
if(flag) return;
for(auto v:G[u]){
if(col[v]==col[u]){
flag=1;
return;
}
if(~col[v]) continue;
col[v]=1-col[u];
color(v);
}
}
void dfs(int u){
++mp[0][a[u]],++mp[1][b[u]];
vis[u]=1,col[u]=0;
for(auto v:G[u]){
if(vis[v]) continue;
dfs(v);
}
}
void work(int u){
++cnt[col[u]][a[u]],++cnt[col[u]+2][b[u]];
vis[u]=1;
for(auto v:G[u]){
if(vis[v]) continue;
work(v);
}
}
void check(){
for(int i=1;i<=n;++i) col[i]=-1,vis[i]=0;
for(int i=1;i<=n;++i) if(col[i]==-1){
flag=0,col[i]=0;
color(i);
if(flag){
mp[0].clear(),mp[1].clear();
dfs(i);
int cnt=0;
for(auto it:mp[0]){
if((mp[0].count(upd(it.first))?mp[0][upd(it.first)]:0)+it.second!=mp[1][it.first]+mp[1][upd(it.first)]){
cout<<"NO"<<endl;
return;
}
if(!flg[it.first.first]) cnt+=abs(it.second-mp[1][it.first]),flg[it.first.first]=1;
}
flg.clear();
if(cnt&1){
cout<<"NO"<<endl;
return;
}
} else{
cnt[0].clear(),cnt[1].clear(),cnt[2].clear(),cnt[3].clear();
work(i);
for(auto it:cnt[0]) if(cnt[1][upd(it.first)]+it.second!=cnt[2][it.first]+cnt[3][upd(it.first)]){
cout<<"NO"<<endl;
return;
}
for(auto it:cnt[1]) if(cnt[0][upd(it.first)]+it.second!=cnt[3][it.first]+cnt[2][upd(it.first)]){
cout<<"NO"<<endl;
return;
}
}
}
cout<<"YES"<<endl;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>T;
while(T--){
cin>>n>>m;
for(int i=1,u,v;i<=m;++i){
cin>>u>>v;
G[u].emplace_back(v);
G[v].emplace_back(u);
}
for(int i=1;i<=n;++i) cin>>a[i].first;
for(int i=1;i<=n;++i){
char c;
cin>>c;
if(c=='R') a[i].second=1;
else a[i].second=0;
}
for(int i=1;i<=n;++i) cin>>b[i].first;
for(int i=1;i<=n;++i){
char c;
cin>>c;
if(c=='R') b[i].second=1;
else b[i].second=0;
}
check();
for(int i=1;i<=n;++i) G[i].clear(),G[i].shrink_to_fit();
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 4ms
memory: 32256kb
input:
3 2 1 1 2 3 4 RR 4 3 BB 3 2 1 2 2 3 1 1 1 RBR 1 1 1 BBB 3 3 1 2 2 3 3 1 1 1 1 RBR 1 1 1 BBB
output:
YES NO YES
result:
ok 3 lines
Test #2:
score: -100
Wrong Answer
time: 466ms
memory: 59048kb
input:
25054 5 10 4 5 4 2 4 3 4 1 5 2 5 3 5 1 2 3 2 1 3 1 12 2 9 10 7 RRRBB 10 2 9 7 12 RRBRB 1 0 4 R 4 R 8 4 4 3 1 5 8 5 6 5 7 2 11 10 9 6 3 5 RBRBBRBR 7 2 10 11 6 5 3 9 RBRBBRBR 7 4 7 2 5 1 5 6 5 4 12 5 9 14 5 12 12 RRBRBRR 14 12 9 5 12 12 5 RBBRBRB 10 1 4 6 5 3 2 9 7 3 11 11 6 8 RRRBRRBBBR 5 3 2 3 7 9 1...
output:
YES YES YES YES YES YES YES YES YES NO YES NO YES NO NO YES YES YES NO YES NO YES YES NO YES YES NO YES NO YES YES YES YES NO YES YES NO YES YES YES YES YES YES YES YES YES YES YES YES YES YES NO NO YES NO YES YES YES YES NO YES YES YES YES YES YES YES YES YES YES YES YES NO YES YES YES NO YES NO NO...
result:
wrong answer 113th lines differ - expected: 'YES', found: 'NO'