QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#462570#8055. BalanceOvO_ZuoWA 83ms12096kbC++143.5kb2024-07-03 21:10:292024-07-03 21:10:30

Judging History

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

  • [2024-07-03 21:10:30]
  • 评测
  • 测评结果:WA
  • 用时:83ms
  • 内存:12096kb
  • [2024-07-03 21:10:29]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
#define fi first
#define se second
#define mkp make_pair
const int N=1e5+5;

int n,m;
int a[N];
vector<pii> edg[N];
vector<int> e[N];

int bel[N];
int siz[N];
int scc;
int stk[N],top;
int dfn[N],low[N];
int kdfn;
void tarjan(int idx,int lst) {
	dfn[idx]=low[idx]=++kdfn;
	stk[++top]=idx;
	for(pii to:edg[idx]) {
		if(!dfn[to.fi]) {
			tarjan(to.fi,to.se);
			low[idx]=min(low[idx],low[to.fi]);
		} else if(to.se!=lst) low[idx]=min(low[idx],dfn[to.fi]);
	}
	if(dfn[idx]==low[idx]) {
		++scc;
		siz[scc]=1;
		for(;stk[top]!=idx;--top) 
			bel[stk[top]]=scc,++siz[scc];
		bel[idx]=scc,--top;
	}
}

int cc=0;
pii f[N][2];
int csiz[N];
int flag=0;
pii chk(pii x,pii y,int sz,int id) {
	if(y.fi+(a[sz]!=a[sz+1])>x.fi) {
		x.fi=y.fi+(a[sz]!=a[sz+1]);
		x.se=((a[sz]!=a[sz+1])?id:y.se);
	} 
	return x;
}
int tag[N];
void col(int idx,int nv,int dv) {
	if(!idx) return;
	tag[idx]=nv;
	col(f[idx][dv].se,nv+(dv?dv:-1),dv);
}
void dfs(int idx,int fa) {
	csiz[idx]=siz[idx];
	for(int to:e[idx]) {
		if(to==fa) continue;
		dfs(to,idx);
		if(flag) return;
		
		if(f[idx][0].fi+f[to][1].fi+
			(a[n-csiz[to]]!=a[n-csiz[to]+1])==cc) {
			tag[1]=f[idx][0].fi+1;
			col(f[idx][0].se,f[idx][0].fi,0);
			if(a[n-csiz[to]]!=a[n-csiz[to]+1]) 
				col(to,cc-f[to][1].fi+1,1);
			else col(f[to][1].se,cc-f[to][1].fi+2,1);
			flag=1;
		}
		if(!flag&&f[idx][1].fi+f[to][0].fi+
				(a[csiz[to]]!=a[csiz[to]+1])==cc) {
			tag[1]=f[to][0].fi+(a[csiz[to]]!=a[csiz[to]+1])+1;
			col(f[idx][1].se,cc-f[idx][1].fi+2,1);
			if(a[csiz[to]]!=a[csiz[to]+1])
				col(to,f[to][0].fi+1,0);
			else col(f[to][0].se,f[to][0].fi,0);
			flag=1;
		}
		
		f[idx][0]=chk(f[idx][0],f[to][0],csiz[to],to);
		f[idx][1]=chk(f[idx][1],f[to][1],n-csiz[to],to);
		csiz[idx]+=csiz[to];
	}
}
int ans[N];
void dfss(int idx,int fa,int c) {
	if(tag[idx]) c=tag[idx];
	ans[idx]=c;
	for(int to:e[idx]) {
		if(to==fa) continue;
		dfss(to,idx,c);
	}
}
void sol() {
	scanf("%d%d",&n,&m);
	int i,j,k;
	for(i=1;i<=n;i++) edg[i].clear(),e[i].clear();
	for(i=1;i<=m;i++) {
		scanf("%d%d",&j,&k);
		edg[j].push_back(mkp(k,i));
		edg[k].push_back(mkp(j,i));
	}
	
	fill(dfn,dfn+1+n,0);
	fill(low,low+1+n,0);
	top=kdfn=scc=0;
	tarjan(1,0);
	
	for(i=1;i<=n;i++) 
		for(pii t:edg[i]) {
			if(bel[i]==bel[t.fi]) continue;
			e[bel[i]].push_back(bel[t.fi]);
		}
	
	a[0]=0;
	for(i=1;i<=n;i++) scanf("%d",&a[i]);
	sort(a+1,a+1+n);
	for(cc=0,i=2;i<=n;i++) 
		if(a[i]!=a[i-1]) ++cc;
	
	fill(tag,tag+1+n,0);
	for(i=0;i<=n;i++) f[i][0]=f[i][1]=mkp(0,0);
	flag=0;
	dfs(1,0);
	if(!flag) return puts("No"),void();
	else {
		puts("Yes");
		unique(a+1,a+1+n);
		dfss(1,0,0);
		for(i=1;i<=n;i++) printf("%d ",ans[bel[i]]);
		puts("");
	}
}
int main() {
	int t;
	scanf("%d",&t);
	while(t) {
		--t;
		sol();
	}
	return 0;
}
/*
给定无向联通图和序列 a,给每个点分配权值使得满足条件
	sigma((u,v) in E) |a[u]-a[v]| = max(a) - min(a)
属于同一环上或不构成链的点权值应当相同
缩点后图构成一棵树
要求等价于找出给节点染色的方式使得同色点缩成一个点后构成一条链
将 a 排序后,若一条边是最后的链中的边,设其分开的两个连通块大小分别为 x,y
当且仅当 a[x]!=a[x+1] 或 a[y]!=a[y+1]
设 f[i][0/1] 表示 i 子树内,从 1/n 开始现在已经断掉了几条边
总共要断掉的边数是确定的,可以转移
*/

详细

Test #1:

score: 100
Accepted
time: 2ms
memory: 12096kb

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
5 4 3 2 1 
No
Yes
2 2 1 3 2 
Yes
2 2 1 1 1 
No

result:

ok ok (5 test cases)

Test #2:

score: -100
Wrong Answer
time: 83ms
memory: 11308kb

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:

Yes
2 2 1 3 
No
Yes
1 1 1 
No
No
Yes
2 1 1 1 
No
No
No
No
No
No
No
Yes
1 1 1 1 1 
Yes
1 2 1 1 1 
Yes
1 1 1 
Yes
2 1 
Yes
1 1 1 1 1 
Yes
2 1 
No
No
Yes
1 1 1 
Yes
1 1 
No
No
Yes
1 1 1 1 1 
No
Yes
1 1 
Yes
1 2 1 1 
No
No
No
Yes
1 1 
No
No
No
Yes
2 1 1 1 1 
Yes
2 1 1 1 
No
No
No
No
Yes
2 3 1 3 3 
Yes
1...

result:

wrong answer ans finds an answer, but out doesn't (test case 9)