NOIP2019トラベル

注意!注意!高エネルギーの前で!多くの場合、タイトルカード!

私たちは、そのすべてを見つけましたGouxue物語はツリーが、その後、直接出てきたことを告げているDFS

だから、木を鳴らしますか?

実際には、長い暴力的な枠消しなどとして、理論的には、複雑さは今までにありqwq

どちら側が、それを削除しましたか?

一般的な操作リングツリー・グループにこのリード:リングトポロジカルソートの需要。具体的な方法がある:リングトポロジーツリーソート、ノードがリングトポロジ内のノードである配列には存在しません。

ちょっとしたトリックが預金側は(私は双方向側のセーブ隣接テーブルを使用)を押しがされたときに最後にリングのエッジを使用


input(x,y,z);
if(x>y) swap(x,y);
add(x,y,z);add(y,x,z);

入金の順番。

彼は良く見ているとき、そのような側面は、重いを見つけるために。(私も特別のコードを見て、表現を理解していないこと〜)

コード


#include<iostream>
#include<cstdio>
#include<queue>

using namespace std;

const int N = 1e5+1;
int n,m,r[N];
int h[N],cnt,delu,delv;//假装 del_u-v 这条边已经被删去了qwq 
struct edge
{
    int nxt;
    int to;
}e[N];
int ans[N],ans1[N];
int qh=0,qt=1,qtp[N],tp[N],vis[N],visu[N],visv[N],tpcnt;//巨丑的代码qwq

inline void readx(int &x)
{
    x=0;char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-48;ch=getchar();}
}

inline void add(register int u,register int v)
{
    e[++cnt].nxt=h[u];
    e[cnt].to=v;
    h[u]=cnt;
}

inline void topo()
{
    for(register int i=1;i<=n;++i) vis[i]=1;
    for(register int u=1;u<=n;++u)
    {
        for(register int i=h[u];i;i=e[i].nxt)
        {
            register int v=e[i].to;
            ++tp[u];++tp[v];
        }
    }
    for(register int i=1;i<=n;++i) if(tp[i]==2) qtp[qt++]=i;

//    for(int i=1;i<=n;++i) printf("%d ",qtp[i]);printf("\n");

    while(qt>qh)
    {
        register int u=qtp[++qh];vis[u]=0;
        for(register int i=h[u];i;i=e[i].nxt)
        {
            register int v=e[i].to;
            tp[u]-=2;tp[v]-=2;
            if(tp[v]==2&&vis[v]) qtp[qt++]=v;
        }
    }
    for(register int u=1;u<=n;++u)
        if(vis[u]==1)
        {
            for(register int i=h[u];i;i=e[i].nxt)
            {
                register int v=e[i].to;
                if(vis[v]==1&&u<v)
                {
                    visu[++tpcnt]=u;visv[tpcnt]=v;
                }
            }
        }
}

inline void update()
{
    for(register int i=1;i<=n;++i) 
    {
        if(ans1[i]==ans[i]) continue;
        if(ans[i]==0) {for(register int j=1;j<=n;++j) ans[j]=ans1[j];return;}
        if(ans1[i]>ans[i]) return;
        //ans1[i]<ans[i] 
        for(register int j=i;j<=n;++j) ans[j]=ans1[j];return;
    }
}

inline void dfs(register int u,register int fa)
{
    ans1[++cnt]=u;
    priority_queue <int,vector<int>,greater<int> > q;//小根堆 
    for(register int i=h[u];i;i=e[i].nxt)
    {
        register int v=e[i].to;
        if(v==fa||(u==delu&&v==delv)||(u==delv&&v==delu)) continue;
        q.push(v);
    }
    while(!q.empty())
    {
        register int v=q.top();q.pop();
        dfs(v,u);
    }
}

signed main()
{
    readx(n);readx(m);
    for(register int i=1;i<=m;++i)
    {
        int u,v;readx(u);readx(v);
        if(u>v) swap(u,v);
        add(u,v);add(v,u);
    }
    cnt=0;
    if(m==n-1)
    {
        dfs(1,0);
        for(register int i=1;i<=n;++i) ans[i]=ans1[i];
    }
    else
    {
        topo();
        for(register int i=1;i<=tpcnt;++i)
        {
            cnt=0;
            delu=visu[i];delv=visv[i];
            dfs(1,0);
            update();
        }
    }
    for(register int i=1;i<=n;++i)
        printf("%d ",ans[i]);
    return 0;
}

実際には、そこに107行に106行のコードを見て、他の場所は、醜い外観を書き、また、qwq来る基本的な独自のものを書くことができるようにすることはできません!

おすすめ

転載: www.cnblogs.com/oierwyh/p/11825256.html