[Codeforces-Gym] (101667C) ---- DFS+记忆化剪枝★

版权声明:本文为博主原创文章,转载请预先通知博主(〃'▽'〃)。 https://blog.csdn.net/m0_37624640/article/details/82939967

题目传送门

题意:

  • 给你一个无权无向图,n个顶点,m个城市。让你找一最长的序列[s1,s2,s3,……sk] 满足顶点si+1的度> si的度,并且si与si+1相邻。

做法:

  • 搜索每个点,判断其邻接点的度是否大于它,是就继续查找。如果这样找,会超时。需要进行剪枝,剪枝的策略就是记忆化,开一个数组保存每个结点能走的最大长度,走过的直接返回最大值。

AC代码:

#include<bits/stdc++.h>
#define IO          ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define pb(x)       push_back(x)
#define sz(x)       (int)(x).size()
#define sc(x)       scanf("%d",&x)
#define abs(x)      ((x)<0 ? -(x) : x)
#define all(x)      x.begin(),x.end()
#define mk(x,y)     make_pair(x,y
#define fin         freopen("in.txt","r",stdin)
#define fout        freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int mod = 1e9+7;
const double PI = 4*atan(1.0);
const int maxm = 1e5+5;
const int maxn = 1e5+5;
const int INF = 0x3f3f3f3f;
vector<int> vec[maxn];
bool vis[maxn];
int step[maxn];
int ans[maxn];
int dfs(int x)
{
    if(!vis[x]){
        vis[x] = true;
        step[x] = 1;
        for(auto it = vec[x].begin();it!=vec[x].end();it++)
        {
            int nex = *it;
            if(sz(vec[nex])>sz(vec[x])){
                int res = dfs(nex);
                step[x] = max(step[x],res+1);
            }
        }
    }
    return step[x];
}
int main()
{
    // fin;
    int n,m,u,v;
    sc(n);sc(m);
    for(int i=0;i<m;i++)
    {
        sc(u);sc(v);
        vec[u].pb(v);
        vec[v].pb(u);
    }
    for(int i=0;i<n;i++){
        ans[i] = dfs(i);
    }
    printf("%d\n",*max_element(ans,ans+n));
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37624640/article/details/82939967