这个题没有认真读的话就会写下以下的DD代码
#include<bits/stdc++.h>
#define N 5010
using namespace std;
int n,m;
int ans[N],actr;
int head[N],ectr;
bool vis[N];
struct Edge{
int from,to,nxt;
}edge[N<<];
void addedge(int from,int to){
ectr++;
edge[ectr].from=from;
edge[ectr].to=to;
edge[ectr].nxt=head[from];
head[from]=ectr;
}
priority_queue<Edge> q;
bool operator < (Edge a,Edge b){
if(a.to != b.to) return a.to > b.to;
else return a.from>b.from;
}
int main()
{
cin>>n>>m;
for(int i=;i<=m;i++)
{
int tra1,tra2;
scanf("%d%d",&tra1,&tra2);
addedge(tra1,tra2);
addedge(tra2,tra1);
}
q.push(Edge{,,});
while (actr!=n)
{
Edge xxx=q.top();
q.pop();
if(vis[xxx.to]) continue;
vis[xxx.to]=true;
ans[++actr]=xxx.to;
for(int i=head[xxx.to];i;i=edge[i].nxt)
q.push(edge[i]);
}
for(int i=;i<=actr;i++)
cout<<ans[i]<<" ";
return ;
}
用单调队列维护一个边队列 然后不断从里面抓出来没有被更新的点 看上去好像很对
实际上换个题它就是对的 但是这不是换的那个题
题中说只有两种走法 一种是从当前走向一个没走过的点 另一种是从走过的回退到走过的
那就意味着 如果你回退了一步 你不能再走到一个你已经走过的点了
这就是为什么单调队列不能用的原因(而且什么玄学下标也救不了)
正解是基环树上的dfs找环断边(logn) 然后树上跑一遍dfs(n)
总复杂度为O(n*logn)
但实际上你不用找环也行 因为这题n2也能过(哈哈哈哈哈哈哈哈哈哈哈哈)
直接暴力短边VANS
但是该学的算法还是要学的 要去做那个数据加强版的
这里埋个坑 以后回来写掉
TAG:SIN_XIII ⑨