通往胜利(题目)的传送门
这 题 其 实 就 是 一 个 拓 扑 排 序 啦 这题其实就是一个拓扑排序啦 这题其实就是一个拓扑排序啦~~~
对 于 一 个 三 元 组 ( q , w , e ) 对于一个三元组(q,w,e) 对于一个三元组(q,w,e)
我 们 连 一 条 q − w , q − e 的 边 , 然 后 对 w 和 e 也 这 样 连 边 我们连一条q-w,q-e的边,然后对w和e也这样连边 我们连一条q−w,q−e的边,然后对w和e也这样连边
那 么 统 计 入 度 ( 也 就 是 被 几 个 三 元 组 包 含 ) 那么统计入度(也就是被几个三元组包含) 那么统计入度(也就是被几个三元组包含)
发 现 入 度 为 1 的 点 只 有 两 个 ( 一 头 一 尾 ) 发现入度为1的点只有两个(一头一尾) 发现入度为1的点只有两个(一头一尾)
举 个 例 子 一 个 排 列 举个例子一个排列 举个例子一个排列
排列:2 3 4 5 6 1
入度:1 2 3 3 2 1
初 始 把 入 度 为 1 的 一 个 入 队 , 比 如 q . p u s h ( 2 ) 初始把入度为1的一个入队,比如q.push(2) 初始把入度为1的一个入队,比如q.push(2)
由 于 2 和 3 连 边 , 2 和 4 连 边 , 那 么 2 和 4 的 入 度 都 减 1 由于2和3连边,2和4连边,那么2和4的入度都减1 由于2和3连边,2和4连边,那么2和4的入度都减1
此 时 3 的 入 度 变 成 1 , 3 入 队 , 一 直 重 复 下 去 . . . . . . . 此时3的入度变成1,3入队,一直重复下去....... 此时3的入度变成1,3入队,一直重复下去.......
但 是 这 样 会 发 现 样 例 都 过 不 去 . . . . . . \color{Red}{但是这样会发现样例都过不去......} 但是这样会发现样例都过不去......
原 因 一 次 拓 扑 操 作 中 可 能 有 多 个 数 入 度 变 为 1 入 队 原因一次拓扑操作中可能有多个数入度变为1入队 原因一次拓扑操作中可能有多个数入度变为1入队
那 么 这 个 时 候 我 们 要 把 初 始 入 度 为 3 的 优 先 入 队 , 初 始 入 度 为 2 的 稍 后 入 队 那么这个时候我们要把初始入度为3的优先入队,初始入度为2的稍后入队 那么这个时候我们要把初始入度为3的优先入队,初始入度为2的稍后入队
至 于 为 什 么 . . . . . . 入 度 为 3 变 成 1 说 明 前 面 两 个 数 都 输 出 了 , 自 己 也 必 须 马 上 输 出 至于为什么......入度为3变成1说明前面两个数都输出了,自己也必须马上输出 至于为什么......入度为3变成1说明前面两个数都输出了,自己也必须马上输出
#include
using namespace std;
const int maxn=1e5+9;
int vis[maxn],n;
vectorvec[maxn];
queueq;
bool find(int q,int w)
{
for(int i=0;ivis[b];
}
int main()
{
cin>>n;
for(int i=1;i<=n-2;i++)
{
int q,w,e;
scanf("%d%d%d",&q,&w,&e);
jin(q,w,e);jin(w,q,e);jin(e,q,w);
}
for(int i=1;i<=n;i++) sort(vec[i].begin(),vec[i].end(),com);//入度大的在前面
int pre=0,last=0;
for(int i=1;i<=n;i++)
{
if(!pre&&vis[i]==1) pre=i;
else if(pre&&vis[i]==1) last=i;
}
q.push(pre);
while(!q.empty())
{
int now=q.front();q.pop();
printf("%d ",now);
for(int i=0;i