NOIP2018 Day2 T1 旅行 - 搜索

枚举删哪条边然后贪心即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define lint long long
#define gc getchar()
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
inline int inn()
{
    int x,ch;while((ch=gc)<'0'||ch>'9');
    x=ch^'0';while((ch=gc)>='0'&&ch<='9')
        x=(x<<1)+(x<<3)+(ch^'0');return x;
}
const int N=5010;
struct edges{
    int to,pre;
}e[N<<1];int h[N],etop,n,dfc,cnt,fa[N];
vector<int> g[N];int has_cyc,vis[N];
inline int add_edge(int u,int v)
{
    return e[++etop].to=v,e[etop].pre=h[u],h[u]=etop;
}
struct node{
    int v[N];
    inline bool operator<(const node &t)const
    { rep(i,1,n) if(v[i]^t.v[i]) return v[i]<t.v[i];return false; }
    inline int show()const{ rep(i,1,n) printf("%d%c",v[i]," \n"[i==n]);return 0; }
}ans,cur;pii bxy,cyc[N];
int dfs(int x,int fa=0)
{
    cur.v[++dfc]=x;
    for(int i=h[x],y;i;i=e[i].pre)
        if((y=e[i].to)^fa)
        {
            if(bxy==mp(x,y)||bxy==mp(y,x)) continue;
            dfs(y,x);
        }
    return 0;
}
int getcyc(int x)
{
    vis[x]=1;if(has_cyc) return 0;
    for(int i=h[x],y;i;i=e[i].pre)
        if((y=e[i].to)^fa[x])
        {
            if(!vis[y]) fa[y]=x,getcyc(y);
            else{
                has_cyc=1,cyc[cnt=1]=mp(x,y);
                while(x^y) cyc[++cnt]=mp(x,fa[x]),x=fa[x];
            }
            if(has_cyc) return 0;
        }
    return 0;
}
int main()
{
    n=inn();int m=inn();
    rep(i,1,m)
    {
        int x=inn(),y=inn();
        g[x].pb(y),g[y].pb(x);
    }
    rep(i,1,n) sort(g[i].begin(),g[i].end());
    rep(x,1,n)
        for(int i=(int)g[x].size()-1;i>=0;i--)
            add_edge(x,g[x][i]);
    if(m==n-1) return dfc=0,dfs(1,0),cur.show();
    else{
        getcyc(1);rep(i,1,n) ans.v[i]=n+1;
        rep(i,1,cnt) dfc=0,bxy=cyc[i],dfs(1),(cur<ans?ans=cur,0:0);
        ans.show();
        return 0;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值