QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#376947#8055. BalancePetroTarnavskyi#WA 2ms7868kbC++205.4kb2024-04-04 19:28:492024-04-04 19:28:49

Judging History

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

  • [2024-04-04 19:28:49]
  • 评测
  • 测评结果:WA
  • 用时:2ms
  • 内存:7868kb
  • [2024-04-04 19:28:49]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define RFOR(i, a, b) for(int i = (a) - 1; i >= (b); i--)
#define SZ(a) int(a.size())
#define ALL(a) a.begin(), a.end()
#define PB push_back
#define MP make_pair
#define F first
#define S second

typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef double db;

const int N = 1 << 17;
const int M = 1 << 18;

int n, m;
int a[N];
vector<PII> g[N];// cleared
bool isBridge[M]; // cleared
bool used[N];// cleared
int tin[N], fup[N], timer;
int comp[N];// cleared
int cntComps;
int szComp[N];// cleared
VI g2[N];// cleared
int szSubtree[N];// cleared
int dpUp[N], dpDown[N];// cleared
PII edgeUp[N], edgeDown[N];// cleared
int cntA[N];// cleared
VI uniqueA;// cleared
int prefSum[N];// cleared
int lca;// cleared
PII edge1, edge2;// cleared
vector<PII> edgesUp, edgesDown;// cleared
int b[N];

void read()
{
	cin >> n >> m;
	FOR(i, 0, m)
	{
		int u, v;
		cin >> u >> v;
		u--;
		v--;
		g[u].PB({v, i});
		g[v].PB({u, i});
	}
	FOR(i, 0, n)
		cin >> a[i];
}

void dfs1(int v, int e)
{
	used[v] = true;
	tin[v] = fup[v] = timer++;
	for (auto [to, i] : g[v])
	{
		if (i == e)
			continue;
		if (used[to])
		{
			fup[v] = min(fup[v], tin[to]);
		}
		else
		{
			dfs1(to, i);
			fup[v] = min(fup[v], tin[to]);
			if (fup[to] > tin[v])
			{
				isBridge[i] = true;
			}
		}
	}
}

void dfs2(int v)
{
	szComp[comp[v]]++;
	for (auto [to, i] : g[v])
	{
		if (comp[to] == -1)
		{
			if (isBridge[i])
			{
				comp[to] = cntComps++;
				g2[comp[v]].PB(comp[to]);
				g2[comp[to]].PB(comp[v]);
			}
			else
			{
				comp[to] = comp[v];
			}
			dfs2(to);
		}
	}
}

void dfs3(int v, int p)
{
	szSubtree[v] = szComp[v];
	dpUp[v] = 0;
	dpDown[v] = SZ(uniqueA);
	for (int to : g2[v])
	{
		if (to == p)
			continue;
		dfs3(to, v);
		
		int j = lower_bound(prefSum, prefSum + SZ(uniqueA) + 1, szSubtree[to]) - prefSum;
		int tmpDpToUp = dpUp[to];
		PII tmpedgeToUp = edgeUp[to];
		if (j <= SZ(uniqueA) && prefSum[j] == szSubtree[to] && dpUp[to] == j - 1)
		{
			tmpDpToUp = j;
			tmpedgeToUp = {v, to};
			
		}
		j = lower_bound(prefSum, prefSum + SZ(uniqueA) + 1, n - szSubtree[to]) - prefSum;
		int tmpDpToDown = dpDown[to];
		PII tmpedgeToDown = edgeDown[to];
		if (j <= SZ(uniqueA) && prefSum[j] == n - szSubtree[to] && dpDown[to] == j + 1)
		{
			tmpDpToDown = j;
			tmpedgeToDown= {v, to};
		}
		
		//cerr << v << " " << to << " " << dpUp[v] << " " << dpDown[to] << endl;
		if (tmpDpToDown <= dpUp[v] + 1)
		{
			lca = v;
			edge1 = edgeUp[v];
			edge2 = tmpedgeToDown;
		}
		if (dpDown[v] <= tmpDpToUp + 1)
		{
			lca = v;
			edge1 = tmpedgeToUp;
			edge2 = edgeDown[v];
		}
		
		if (tmpDpToUp > dpUp[v])
		{
			dpUp[v] = tmpDpToUp;
			edgeUp[v] = tmpedgeToUp;
		}
		if (tmpDpToDown < dpDown[v])
		{
			dpDown[v] = tmpDpToDown;
			edgeDown[v] = tmpedgeToDown;
		}
		szSubtree[v] += szSubtree[to];
	}
	if (dpUp[v] == SZ(uniqueA) - 1)
	{
		lca = v;
		edge1 = edgeUp[v];
		edge2 = {-1, -1};
	}
	if (dpDown[v] == 1)
	{
		lca = v;
		edge1 = {-1, -1};
		edge2 = edgeDown[v];
	}
}

void findEdgesUp(PII edge)
{
	while (edge.F != -1)
	{
		auto [v, to] = edge;
		edgesUp.PB(edge);
		//cerr << "up " << to << " " << dpUp[to] << endl;
		if (dpUp[to] == 0)
			break;
		edge = edgeUp[to];
	}
}

void findEdgesDown(PII edge)
{
	while (edge.F != -1)
	{
		auto [v, to] = edge;
		edgesDown.PB(edge);
		//cerr << "down " << to << " " << dpDown[to] << endl;
		if (dpDown[to] == SZ(uniqueA))
			break;
		edge = edgeDown[to];
	}
}

void dfs4(int v)
{
	for (int to : g2[v])
	{
		if (b[to] == -1)
		{
			b[to] = b[v];
			dfs4(to);
		}
	}
}



void solve()
{
	fill(used, used + n, false);
	fill(isBridge, isBridge + m, false);
	timer = 0;
	dfs1(0, -1);
	/*FOR(v, 0, n)
	{
		for (auto [to, i] : g[v])
		{
			if (isBridge[i])
			{
				cerr << "bridge " << v << " " << to << endl;
			}
		}
	}*/
	fill(comp, comp + n, -1);
	comp[0] = 0;
	cntComps = 1;
	fill(szComp, szComp + n, 0);
	dfs2(0);
	uniqueA = VI(a, a + n);
	sort(ALL(uniqueA));
	uniqueA.erase(unique(ALL(uniqueA)), uniqueA.end());
	FOR(i, 0, n + 1)
		cntA[i] = 0;
	FOR(i, 0, n)
	{
		cntA[a[i]]++;
	}
	prefSum[0] = 0;
	FOR(i, 0, SZ(uniqueA))
	{
		prefSum[i + 1] = prefSum[i] + cntA[uniqueA[i]];
	}
	lca = -1;
	dfs3(0, -1);
	if (lca == -1)
	{
		cout << "No\n";
		return;
	}
	edgesUp.clear();
	edgesDown.clear();
	findEdgesUp(edge1);
	findEdgesDown(edge2);
	assert(SZ(edgesUp) + SZ(edgesDown) >= SZ(uniqueA) - 1);
	reverse(ALL(edgesUp));
	edgesUp.resize(SZ(uniqueA) - 1 - SZ(edgesDown));
	FOR(i, 0, cntComps)
		b[i] = -1;
	FOR(i, 0, SZ(edgesUp))
	{
		auto [u, v] = edgesUp[i];
		b[u] = b[v] = uniqueA[i];
		dfs4(v);
		b[u] = -1;
	}
	FOR(i, 0, SZ(edgesDown))
	{
		auto [u, v] = edgesDown[i];
		b[u] = b[v] = uniqueA[i + SZ(edgesUp)];
		dfs4(u);
		b[v] = -1;
	}
	FOR(i, 0, cntComps)
		if (b[i] == -1)
		{
			b[i] = uniqueA.back();
		}
	cout << "Yes\n";
	FOR(i, 0, n)
	{
		if (i)
			cout << " ";
		cout << b[comp[i]];
	}
	cout << "\n";
}

void clear()
{
	FOR(i, 0, n)
	{
		g[i].clear();
		g2[i].clear();
	}
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	int t;
	cin >> t;
	while (t--)
	{
		read();
		solve();
		clear();
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 2ms
memory: 7868kb

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
1 1 1 2 2
No

result:

wrong answer max - min = 1, but sum of difference = 2 (test case 4)