QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#404525 | #8055. Balance | KLPP | TL | 6ms | 50668kb | C++17 | 6.8kb | 2024-05-04 02:31:18 | 2024-05-04 02:31:18 |
Judging History
answer
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long int lld;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
#define rep(i,a,b) for(int i=a;i<b;i++)
#define trav(a,v) for(auto a:v)
// Be careful with duplicate edges! This algorithm only works with NO duplicate edges
struct Bridges {
vector<int> disc, low; vector<pair<int, int> > is_bridge;
int Time;
Bridges(vector< vector<int> > &adj) {
disc = low = vector<int> ((int) adj.size());
is_bridge.clear(); Time = 0;
for (int i = 0; i < (int) adj.size(); i++) if (!disc[i]) dfs(adj, i);
}
void dfs(vector< vector<int> > &graph, int node, int p = -1) {
disc[node] = low[node] = ++Time;
for (auto to : graph[node]) {
if (to == p) continue;
if (!disc[to]) {
dfs(graph, to, node); low[node] = min(low[node], low[to]);
if (disc[node] < low[to]) is_bridge.emplace_back(node, to),is_bridge.emplace_back(to,node);
} else low[node] = min(low[node], disc[to]);
}
}
};
const int MX=1'000'000;
vector<int> cc[MX];
int vis[MX];
set<pair<int,int> >br;
map<pair<int,int>,int> dupl;
void DFS(int node,vector<vector<int> >&nei){
cc[vis[node]].push_back(node);
trav(a,nei[node]){
if(vis[a]==-1 && br.find({node,a})==br.end()){
vis[a]=vis[node];
DFS(a,nei);
}
}
}
int sz[MX];
vector<int> tr[MX];
vector<lld> PR;
vector<lld> SF;
vector<lld> VV;
pair<int,int> DPpref[MX];
pair<int,int> DPsuf[MX];
int subsz[MX];
int finpar[MX];
void calcsz(int node, int par=-1){
subsz[node]=sz[node];
trav(a,tr[node]){
if(a!=par){
calcsz(a,node);
subsz[node]+=subsz[a];
}
}
}
void calcDP(int node, int par=-1){
DPpref[node]={1,-1};
DPsuf[node]={1,-1};
trav(a,tr[node]){
if(a==par)finpar[node]=a;
if(a!=par){
calcDP(a,node);
DPpref[node]=max(DPpref[node],{DPpref[a].first,a});
DPsuf[node]=max(DPsuf[node],{DPsuf[a].first,a});
}
}
if(DPpref[node].first<(int)PR.size()){
if(PR[DPpref[node].first]==subsz[node])DPpref[node].first++;
}
if(DPsuf[node].first<(int)SF.size()){
if(SF[DPsuf[node].first]==subsz[node])DPsuf[node].first++;
}
}
set<pair<int,int> > BLOCK;
int ans[MX];
int startMn;
int startMx;
int CTpoint;
multiset<pair<lld,int>> mmp;
void calcFin(int node, int par=-1){
trav(a,tr[node]){
if(a!=par){
calcFin(a,node);
}
}
if(DPpref[node].first==(int)PR.size()){
startMn=node;
startMx=-1;
CTpoint=0;
}
if(DPsuf[node].first==(int)SF.size()){
startMn=-1;
startMx=node;
CTpoint=PR.size()-2;
}
mmp.clear();
trav(a,tr[node]){
if(a!=par){
mmp.insert({DPsuf[a].first,a});
}
}
trav(a,tr[node]){
if(a!=par){
auto it2=mmp.find(pair<lld,int>(DPsuf[a].first,a));
mmp.erase(it2);
auto it=mmp.lower_bound({(int)PR.size()-DPpref[a].first,-1});
if(it!=mmp.end()){
startMn=a;
startMx=it->second;
assert(DPsuf[it->second].first+DPpref[a].first>=PR.size());
CTpoint=PR.size()-DPpref[a].first-1;
//cout<<CTpoint<<" "<<DPsuf[it->second].first<<" "<<DPpref[a].first<<endl;
}
mmp.insert({DPsuf[a].first,a});
}
}
}
void DFSfinal(int node, int par=-1, int D=0){
ans[node]=D;
trav(a,tr[node]){
if(a==par)continue;
if(BLOCK.find({node,a})!=BLOCK.end()){
DFSfinal(a,node,D+1);
}else DFSfinal(a,node,D);
}
}
int finans[MX];
void solve(){
BLOCK.clear();
PR.clear();
SF.clear();
VV.clear();
dupl.clear();
int n,m;
cin>>n>>m;
vector<vector<int> >nei(n);
rep(i,0,m){
int x,y;
cin>>x>>y;
x--;y--;
nei[x].push_back(y);
nei[y].push_back(x);
dupl[{x,y}]++;
dupl[{y,x}]++;
}
Bridges B(nei);
map<lld,lld> M;
rep(i,0,n){
lld x;
cin>>x;
M[x]++;
}
br.clear();
trav(a,B.is_bridge){
br.insert(a);
}
trav(a,dupl){
if(a.second>1){
if(br.find(a.first)!=br.end()){
br.erase(a.first);
}
}
}
rep(i,0,n)vis[i]=-1,cc[i].clear();
int cnt=0;
rep(i,0,n){
if(vis[i]==-1){
vis[i]=cnt;
DFS(i,nei);
sz[cnt]=cc[cnt].size();
cnt++;
}
}
rep(i,0,n)tr[i].clear();
//rep(i,0,n)cout<<vis[i]<<" ";
//cout<<"\n";
//rep(i,0,cnt)cout<<sz[i]<<" ";
//cout<<"\n";
trav(a,br){
//cout<<vis[a.first]<<"E "<<vis[a.second]<<"\n";
tr[vis[a.first]].push_back(vis[a.second]);
}
vector<int> VV2;
trav(a,M){
VV2.push_back(a.first);
VV.push_back(a.second);
//cout<<a.first<<" "<<a.second<<endl;
}
PR.push_back(0);
trav(a,VV)PR.push_back(a+PR[PR.size()-1]);
reverse(VV.begin(),VV.end());
SF.push_back(0);
trav(a,VV)SF.push_back(a+SF[SF.size()-1]);
reverse(VV.begin(),VV.end());
rep(i,0,cnt)finpar[i]=-1;
//trav(a,PR)cout<<a<<"A ";
//cout<<endl;
calcsz(0);
calcDP(0);
startMn=-1;
startMx=-1;
CTpoint=-1;
calcFin(0);
if(startMn==-1 && startMx==-1){
cout<<"No\n";
return;
}
cout<<"Yes\n";
//trav(a,PR)cout<<a<<" ";
//cout<<endl;
//cout<<startMn<<" "<<startMx<<endl;
pair<lld,lld> Pl={-1,-1};
pair<lld,lld> Pr={-1,-1};
if(startMn!=-1)Pl=DPpref[startMn];
if(startMx!=-1)Pr=DPsuf[startMx];
int START=-1;
if(startMn==-1)START=startMx;
//cout<<startMn<<" "<<startMx<<"\n";
set<lld> SPR,SSF;
trav(a,PR)SPR.insert(a);
int LAST=-1;
vector<pair<int,int> >ADDEDGES;
while(startMn!=-1){
int u=startMn;
int v=finpar[u];
if(v!=-1){
if(SPR.find(subsz[u])!=SPR.end()){
BLOCK.insert({u,v});
BLOCK.insert({v,u});
}
}
LAST=startMn;
startMn=Pl.second;
if(startMn==-1)break;
Pl=DPpref[Pl.second];
}
if(START==-1)START=LAST;
trav(a,SF)SSF.insert(a);
while(startMx!=-1){
int u=startMx;
int v=finpar[u];
if(v!=-1){
if(SPR.find(subsz[u])!=SPR.end()){
ADDEDGES.push_back({u,v});
}
}
startMx=Pr.second;
if(startMx==-1)break;
Pr=DPsuf[Pr.second];
}
reverse(ADDEDGES.begin(),ADDEDGES.end());
//cout<<CTpoint<<" "<<ADDEDGES.size()<<endl;
if(CTpoint>ADDEDGES.size()){
while(true){
}
}
rep(i,0,CTpoint){
BLOCK.insert({ADDEDGES[i].first,ADDEDGES[i].second});
BLOCK.insert({ADDEDGES[i].second,ADDEDGES[i].first});
}
//trav(a,BLOCK)cout<<a.first<<" "<<a.second<<"\n";
DFSfinal(START);
rep(i,0,cnt){
trav(a,cc[i]){
finans[a]=VV2[ans[i]];
}
}
rep(i,0,n)cout<<finans[i]<<" ";
cout<<"\n";
//cout<<endl;
//rep(i,0,cnt)cout<<VV2[ans[i]]<<" ";
//cout<<endl;
//cout<<startMn<<" "<<startMx<<"\n";
//cout<<PR.size()<<endl;
//rep(i,0,cnt)cout<<subsz[i]<<" ";
//cout<<"\n";
//rep(i,0,cnt)cout<<DPpref[i].first<<","<<DPpref[i].second<<" ";
//cout<<"\n";
//rep(i,0,cnt)cout<<DPsuf[i].first<<","<<DPsuf[i].second<<" ";
//cout<<"\n";
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
int tt=1;
cin>>tt;
while(tt--){
solve();
}
}
详细
Test #1:
score: 100
Accepted
time: 6ms
memory: 50668kb
input:
5 5 4 1 2 2 3 3 4 4 5 1 2 3 4 5 5 4 1 2 1 3 1 4 1 5 1 2 3 4 5 5 4 1 2 1 3 1 4 1 5 1 2 2 2 3 5 6 1 2 1 2 2 3 3 4 4 5 3 5 1 2 1 2 1 2 2 1 2 1 2 1 2
output:
Yes 1 2 3 4 5 No Yes 2 3 2 2 1 Yes 2 2 1 1 1 No
result:
ok ok (5 test cases)
Test #2:
score: -100
Time Limit Exceeded
input:
100000 4 3 4 2 1 3 2 1 2 1 3 2 5 7 2 5 5 3 2 3 5 1 4 3 2 4 4 3 1 3 1 1 2 3 2 2 1 2 3 1 1 1 4 7 3 4 1 4 2 3 4 3 4 2 3 1 4 3 2 3 3 2 4 6 2 4 3 1 1 2 1 2 2 3 4 2 1 1 3 3 4 7 3 2 4 2 1 2 3 4 3 2 2 4 3 4 2 1 1 1 5 5 3 2 1 5 4 5 4 3 2 1 1 2 2 3 2 3 5 2 3 1 3 3 1 3 1 2 1 3 2 3 2 3 2 1 2 1 1 2 1 1 2 3 2 1 1...