目录
1.Problem
2.Input
3.Output
4.Examples
4.1input
4.2output
5.Code
6.Conclusion
Nezzar designs a brand new game "Hidden Permutations" and shares it with his best friend, Nanako.
At the beginning of the game, Nanako and Nezzar both know integers nn and mm. The game goes in the following way:
However, Nezzar accidentally knows Nanako's unordered pairs and decides to take advantage of them. Please help Nezzar find out two permutations pp and qq such that the score is maximized.
The first line contains a single integer tt (1≤t≤5⋅1051≤t≤5⋅105) — the number of test cases.
The first line of each test case contains two integers n,mn,m (1≤n≤5⋅105,0≤m≤min(n(n−1)2,5⋅105)1≤n≤5⋅105,0≤m≤min(n(n−1)2,5⋅105)).
Then mm lines follow, ii-th of them contains two integers li,rili,ri (1≤li,ri≤n1≤li,ri≤n, li≠rili≠ri), describing the ii-th unordered pair Nanako chooses. It is guaranteed that all mm unordered pairs are distinct.
It is guaranteed that the sum of nn for all test cases does not exceed 5⋅1055⋅105, and the sum of mm for all test cases does not exceed 5⋅1055⋅105.
For each test case, print two permutations p1,p2,…,pnp1,p2,…,pn and q1,q2,…,qnq1,q2,…,qn such that the score Nezzar gets is maximized.
3
4 2
1 2
3 4
6 4
1 2
1 3
3 5
3 6
2 1
1 2
1 2 3 4
3 4 1 2
2 3 4 1 6 5
1 4 3 2 5 6
1 2
1 2
#include
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair pii;
typedef pair pll;
template bool chkmax(T &x, T y) { return x < y ? x = y, true : false; }
template bool chkmin(T &x, T y) { return x > y ? x = y, true : false; }
int readint() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
const int MAXN = 500005;
const int MAXM = 1000005;
int n, m, tot;
int v[MAXM], nxt[MAXM], h[MAXN], f[MAXN], du[MAXN], q[MAXN], ans1[MAXN], ans2[MAXN];
bool vis[MAXN];
vector adj[MAXN];
int getf(int x) {
return x == f[x] ? x : f[x] = getf(f[x]);
}
void addedge(int x, int y) {
v[++tot] = y; nxt[tot] = h[x]; h[x] = tot; du[y]++;
v[++tot] = x; nxt[tot] = h[y]; h[y] = tot; du[x]++;
}
void work() {
n = readint();
m = readint();
for (int i = 1; i <= n + 1; i++)
h[i] = du[i] = vis[i] = 0;
tot = 0;
for (int i = 1; i <= n; i++) {
adj[i].clear();
f[i] = i;
}
int x, y;
for (int i = 1; i <= m; i++) {
x = readint();
y = readint();
adj[x].pb(y);
adj[y].pb(x);
}
for (int i = 1; i <= n; i++) {
vis[i] = 1;
for (auto v : adj[i])
vis[v] = 1;
int pl = 0;
for (int j = 1; j <= adj[i].size() + 2; j++)
if (!vis[j])
pl = j;
if (pl <= n) {
int fx = getf(i), fy = getf(pl);
if (fx != fy)
f[fx] = fy, addedge(i, pl);
}
vis[i] = 0;
for (auto v : adj[i])
vis[v] = 0;
}
int front = 0, rear = 0, cnt = 0;
for (int i = 1; i <= n; i++)
if (du[i] == 1)
q[rear++] = i;
for (int i = 1; i <= n; i++)
if (du[i] == 0)
ans1[i] = ans2[i] = ++cnt;
while (front < rear) {
int t = q[front++], to;
if (vis[t])
continue;
for (int p = h[t]; p; p = nxt[p])
if (!vis[v[p]])
to = v[p];
vis[to] = 1;
vector vec(1, to);
for (int p = h[to]; p; p = nxt[p]) {
if (!vis[v[p]] && du[v[p]] == 1) {
vec.pb(v[p]);
vis[v[p]] = 1;
}
}
for (int i = 0; i < vec.size(); i++)
ans1[vec[i]] = cnt + i + 1;
for (int i = 1; i < vec.size(); i++)
ans2[vec[i]] = cnt + i;
ans2[to] = cnt + vec.size();
cnt += vec.size();
for (int p = h[to]; p; p = nxt[p])
if (!vis[v[p]] && (--du[v[p]]) == 1)
q[rear++] = v[p];
}
for (int i = 1; i <= n; i++)
printf("%d ", ans1[i]);
printf("\n");
for (int i = 1; i <= n; i++)
printf("%d ", ans2[i]);
printf("\n");
}
int main() {
int T = readint();
while (T--)
work();
return 0;
}
这段代码实现了一个图论算法。具体来说,它解决了一个图的遍历和连通性问题。以下是代码的主要功能:
1.通过 readint 函数读取输入。
2.使用并查集维护图中的连通分量,并在发现新的边时将其添加到图中。
3.找到每个节点的度数,并将度数为1的节点加入队列。
4.从队列中取出节点,沿着图的边进行遍历,更新节点的连通分量,并将度数为1的相邻节点加入队列。
5.输出两个排列,其中第一个排列表示节点在第一次遍历时的顺序,第二个排列表示节点在第二次遍历时的顺序。总体而言,这段代码对一个无向图进行了一系列遍历和处理,最终输出了两个排列,表示两次遍历的顺序。