noip 2018 Day2 T1 旅行

本文介绍了一种通过暴力删边和枚举的方法来确定一个无向图是否能形成一棵树,并找到一种可能的树形结构。使用深度优先搜索(DFS)遍历图,检查并记录每个节点的访问顺序,以此验证图是否连通且无环,最终输出一个可能的树形结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

暴力删边,暴力枚举

#include <bits/stdc++.h>

using namespace std;

#define MAXM 5010

inline int read()
{
    int x = 0,ff = 1;char ch = getchar();
    while(!isdigit(ch))
    {
        if(ch == '-') ff = -1;
        ch = getchar();
    }
    while(isdigit(ch))
    {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    return x * ff;
}

inline void write(int x)
{
    if(x < 0) putchar('-'),x = -x;
    if(x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

int a,b,x,y,dx,dy,top = 0,c[MAXM],vis[MAXM],T[MAXM],m[MAXM],e[MAXM][5]; 
vector < int > q[MAXM];

inline void dfs(int x)
{

    T[++top] = x; vis[x] = true;
    int l = q[x].size();
    for(int i = 0;i < l;++i)
    {        
        int y = q[x][i];
        if((vis[y]) || (x == dx && y == dy) || (x == dy && y == dx)) continue;
        dfs(y);
    }
    return ;
}

inline void check()
{
    for(int i = 1;i <= a;++i)
    {
        if(m[i] != T[i])
        {
            if(m[i] < T[i]) return ;
            break;
        }
    }
    for(int i = 1;i <= a;++i)
    m[i] = T[i];
}

int main()
{ 
    memset(m,0x3f,sizeof(m));
    a = read(); b = read();
    for(int i = 1;i <= b;++i)
    {
        int x,y;
        x = read(); y = read();
        q[x].push_back(y);
        q[y].push_back(x);
        e[i][0] = x;
        e[i][1] = y;
    }
    for(int i = 1;i <= a;++i)
        sort(q[i].begin(),q[i].end());
    if(b == a - 1)    
    {
        dx = -1; dy = -1;
        dfs(1);
        for(int i = 1;i <= a;++i)
        write(T[i]),putchar(' ');
    }
    else
    {
        for(int i = 1;i <= b;++i)
        {
            top = 0;
            dx = e[i][0];
            dy = e[i][1];
            memset(T,0,sizeof(T));
            memset(vis,false,sizeof(vis));
            dfs(1);
            if(top != a) continue;
            check(); 
        } 
        for(int i = 1;i <= a;++i)
        write(m[i]),putchar(' ');
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/AK-ls/p/10385363.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值