练习赛补题-----C - Game Map dp

题意:给定一个图,在图上要求找一个最长链,使得后面一个点的度数比前一个点的度数大,问最长的长度是多少?

可以利用拓扑排序的方式进行dp,首先更新dp值全为1,然后遍历度数,每次找出最小的度数,更新完dp之后,删去这些点,再找最小的度数。。。。,最后的最大的dp值就是答案。
dp[i]代表到i点的最长的链的长度

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
const int MAXN = 1e5 + 5;

vector<int>ve[MAXN];
int deg[MAXN];
int dp[MAXN];
vector<int>ans[MAXN];

int main()
{
    int n,m;
    memset(deg,0,sizeof(deg));
    scanf("%d %d",&n,&m);
    int MIN = inf;
    for(int i = 0;i < m;++i){
        int x,y;
        scanf("%d %d",&x,&y);
        ve[x].pb(y);
        ve[y].pb(x);
        deg[x]++;deg[y]++;
    }
    int len = -1;
    for(int i = 0;i < n;++i){
        ans[deg[i]].pb(i);
        len = max(len,deg[i]);
    }
    for(int i = 0;i < n;++i){
        dp[i] = 1;
    }
    for(int i = 0;i <= len;++i){
        if(ans[i].size() > 0){
            for(int j = 0;j < ans[i].size();++j){
                int v = ans[i][j];
                for(int k = 0;k < ve[v].size();++k){
                    int p = ve[v][k];
                    if(deg[p] < deg[v])
                        dp[v] = max(dp[v],dp[p] + 1);
                }
            }
        }
    }
    int MAX = 1;
    for(int i = 0;i < n;++i){
        MAX = max(MAX,dp[i]);
    }
    printf("%d\n",MAX);
    return 0;
}


下面还有一种dp的方法,利用dfs来解决,dp[i]代表以i节点开始的最长链的长度,
dp[i] = max(dp[i],dp[k] + 1);k是i的邻接点,且度数大于i点

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
const int MAXN = 1e5 + 5;

vector<int>ve[MAXN];
int dp[MAXN];
int n,m;
int deg[MAXN];

int dfs(int id)
{
    if(dp[id]) return dp[id];
    int sum = 1;
    int len = ve[id].size();
    for(int i = 0;i < len;++i){
        int v = ve[id][i];
        if(deg[v] > deg[id]){
            sum = max(sum,dfs(v) + 1);
        }
    }
    dp[id] = sum;
    return sum;
}

int main()
{
    scanf("%d %d",&n,&m);
    memset(dp,0,sizeof(dp));
    memset(deg,0,sizeof(deg));
    for(int i = 0;i < m;++i){
        int a,b;
        scanf("%d %d",&a,&b);
        ve[a].pb(b);
        ve[b].pb(a);
        deg[a]++;deg[b]++;
    }
    int MAX = 1;
    for(int i = 0;i < n;++i){
        MAX = max(MAX,dfs(i));
    }
    printf("%d\n",MAX);
    return 0;
}

发布了269 篇原创文章 · 获赞 33 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_36386435/article/details/89041637
今日推荐