1. 程式人生 > >[Codeforces-Gym] (101667C) ---- DFS+記憶化剪枝★

[Codeforces-Gym] (101667C) ---- DFS+記憶化剪枝★

題目傳送門

題意:

  • 給你一個無權無向圖,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;
}