zoukankan      html  css  js  c++  java
  • 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 ⑨

  • 相关阅读:
    vue子组件获取父组件方法
    css hack
    【Educational Codeforces Round 87 (Rated for Div. 2)】前4题
    【某次ks】20200512
    NoI Online 2反思
    RMQ&LCA
    杂谈
    高手训练矩乘T3
    0118ACM自闭赛
    网络流初步学习笔记
  • 原文地址:https://www.cnblogs.com/SINXIII/p/10380929.html
Copyright © 2011-2022 走看看