League of Leesins ( 拓扑排序 )
题目链接:https://codeforces.com/contest/1255/problem/C
题意:把一个序列分成三部分三部分,无序给出,求原始序列。For example, if 𝑛=5 and 𝑝=[1,4,2,3,5], then the original array 𝑞 will be [(1,4,2),(4,2,3),(2,3,5)]. Bob can then rearrange the numbers within each triple and the positions of the triples to get [(4,3,2),(2,3,5),(4,1,2)]。
Input
5
4 3 2
2 3 5
4 1 2
Output
1 4 2 3 5
思路:因为原始序列每个点都和左右相邻的2个点相连,直接建一张图,来拓扑排序。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
struct node {
int to,nxt;
}e[maxn*6];
int head[maxn];
int du[maxn];
int via[maxn];
int cnt;
int n;
void addage( int u, int v )
{
e[cnt].to = v;
e[cnt].nxt = head[u];
head[u] = cnt++;
e[cnt].to = u;
e[cnt].nxt = head[v];
head[v] = cnt++;
}
void topu( int node )
{
queue <int> Q;
Q.push(node);
via[node] = 1;
while ( !Q.empty() ) {
int t = Q.front(); Q.pop();
cout << t << " ";
for ( int i=head[t]; i!=-1; i=e[i].nxt ) {
int x = e[i].to;
if ( via[x]==0 ) {
du[x] --;
if ( du[x]==1 ) {
Q.push(x);
via[x] = 1;
}
}
}
}
}
int main()
{
int x,y,z;
cin >> n;
memset(head,-1,sizeof(head));
memset(du,0,sizeof(du));
memset(via,0,sizeof(via));
for ( int i=0; i<n-2; i++ ) {
scanf("%d %d %d",&x,&y,&z);
addage(x,y);
addage(x,z);
addage(y,z);
du[x]++; du[y]++; du[z]++;
}
int isp1 = 0, isp2 = 0;
for ( int i=1; i<=n; i++ ) {
if ( du[i]==1 ) {
if ( isp1==0 ) isp1 = i;
else du[i]=3;
}
}
for ( int i=head[isp1]; i!=-1; i=e[i].nxt ) {
int x = e[i].to;
if ( du[x]==2 ) isp2=x;
}
for ( int i=1; i<=n; i++ ) {
if ( du[i]==2 && i!=isp2 ) {
du[i]++;
}
}
topu(isp1);
return 0;
}