로곡 P1137 여행 계획(토폴로지 순서+dp)

9825 단어
DAG에서 토폴로지 정렬은 dp의 순서를 정할 수 있다
그림의 정보를 토폴로지 순서로 바꾸다
조심해서 움직일 때는 옆으로 움직여야 돼요.
이 문제의 dp는 도표법으로 한다
#include
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;

const int MAXN = 1e5 + 10;
struct Edge{ int to, next; };
Edge e[MAXN << 1];
int head[MAXN], d[MAXN];
int topo[MAXN], dp[MAXN]; 
int n, m, cnt, tot;

void AddEdge(int from, int to)
{
    e[tot] = Edge{to, head[from]};
    head[from] = tot++;
}

void read(int& x)
{
    int f = 1; x = 0; char ch = getchar();
    while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar(); }
    while(isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); }
    x *= f;
}

void toposort()
{
    queue<int> q;
    _for(i, 1, n)
        if(!d[i])
            q.push(i);
    while(!q.empty())
    {
        int u = q.front(); q.pop();
        topo[++cnt] = u;
        for(int i = head[u]; ~i; i = e[i].next)
        {
            int v = e[i].to;
            if(--d[v] == 0) q.push(v);
        }
    }
}

int main()
{
    memset(head, -1, sizeof(head)); tot = 0;
    read(n); read(m);
    
    _for(i, 1, m)
    {
        int u, v; 
        read(u); read(v);
        AddEdge(u, v);
        d[v]++;
    }
    
    toposort();
    _for(i, 1, n) dp[i] = 1;
    _for(i, 1, n)
    {
        int u = topo[i];
        for(int i = head[u]; ~i; i = e[i].next)
        {
            int v = e[i].to;
            dp[v] = max(dp[v], dp[u] + 1);
        }
    }
    _for(i, 1, n) printf("%d
", dp[i]); return 0; }

기억으로 검색할 수도 있고.
#include
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;

const int MAXN = 1e5 + 10;
struct Edge{ int to, next; };
Edge e[MAXN << 1];
int head[MAXN], dp[MAXN];
int n, m, cnt, tot;

void AddEdge(int from, int to)
{
    e[tot] = Edge{to, head[from]};
    head[from] = tot++;
}

void read(int& x)
{
    int f = 1; x = 0; char ch = getchar();
    while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar(); }
    while(isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); }
    x *= f;
}

int dfs(int u)
{
    if(dp[u] != -1) return dp[u];
    dp[u] = 1;
    for(int i = head[u]; ~i; i = e[i].next)
    {
        int v = e[i].to;
        dp[u] = max(dp[u], dfs(v) + 1);
    }
    return dp[u];
}

int main()
{
    memset(head, -1, sizeof(head)); tot = 0;
    read(n); read(m);
    
    _for(i, 1, m)
    {
        int u, v; 
        read(u); read(v);
        AddEdge(v, u);
    }
    
    memset(dp, -1, sizeof(dp));
    _for(i, 1, n) printf("%d
", dfs(i)); return 0; }

 
전재 대상:https://www.cnblogs.com/sugewud/p/9883766.html

좋은 웹페이지 즐겨찾기