QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#404525#8055. BalanceKLPPTL 6ms50668kbC++176.8kb2024-05-04 02:31:182024-05-04 02:31:18

Judging History

你现在查看的是最新测评结果

  • [2024-05-04 02:31:18]
  • 评测
  • 测评结果:TL
  • 用时:6ms
  • 内存:50668kb
  • [2024-05-04 02:31:18]
  • 提交

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...

output:


result: