NOIp 2018 D2T1 旅行//未完成

这个题没有认真读的话就会写下以下的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<<1];
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=1;i<=m;i++)
    {
        int tra1,tra2;
        scanf("%d%d",&tra1,&tra2);
        addedge(tra1,tra2);
        addedge(tra2,tra1);
    }
    q.push(Edge{0,1,0});
    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=1;i<=actr;i++)
        cout<<ans[i]<<" ";
    return 0;
}

用单调队列维护一个边队列 然后不断从里面抓出来没有被更新的点 看上去好像很对

实际上换个题它就是对的 但是这不是换的那个题

题中说只有两种走法  一种是从当前走向一个没走过的点 另一种是从走过的回退到走过的

那就意味着 如果你回退了一步 你不能再走到一个你已经走过的点了

这就是为什么单调队列不能用的原因(而且什么玄学下标也救不了)

正解是基环树上的dfs找环断边(logn) 然后树上跑一遍dfs(n)

总复杂度为O(n*logn)

但实际上你不用找环也行 因为这题n2也能过(哈哈哈哈哈哈哈哈哈哈哈哈)

直接暴力短边VANS

但是该学的算法还是要学的 要去做那个数据加强版

这里埋个坑 以后回来写掉

TAG:SIN_XIII ⑨

转载于:https://www.cnblogs.com/SINXIII/p/10380929.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值