zoukankan      html  css  js  c++  java
  • 洛谷 p2661 信息传递(链式前向星建图)

    链式前向星

    最近看图论的板子总是有这种代码

    
    struct Edge{
        int next;   // 下一条边的下标
        int to;     // 当前边的指向
        int w;      // 当前边的权值
    };
    
    Edge edge[maxn*2];  
    int tot;        // 当前边的下标
    void addEdge(int u,int v,int w){
        edge[++tot].next = head[u];
        edge[tot].to = v;
        edge[tot].w = w;
        head[u] = tot;  // 头插法
    }
    
    

    实质就是链表的运用.
    (Edge.next)代表指向下一条边的指针,(head[u])为节点(u)的头节点,每次加入新边时用头插法.

    遍历点(u)可用

        for(int i = head[u];i;i = edge[i].next)
    

    题目: luogo P2661 信息传递

    • 题目大意: 每个点只有一个出度,求最短环(必存在)
    • 思路: (Tarjan)判环,每次跑(dfs)时将所有节点加入栈中,如果新节点已经在栈中,则存在环,从栈中找到新节点,距离栈顶的距离即为环长.
    #include<bits/stdc++.h>
    #define ll long long 
    #define FOR(i,n) for(int i =1; i <= n;++i ) 
    #define FOR0(i,n) for(int i =0; i < n;++i )  
    #define inf 0x3f3f3f3f
    #define EPS (1e-8)
    #define ALL(T)  T.begin(),T.end()
    using namespace std;
    
    const int maxn = 200010;
    int n;
    inline int input(){
        int res = 0;
        char c;
        c = getchar();
        while('0' <= c && c<='9'){
            res = res*10 + (c-'0');
            c = getchar();
        }
        return res;
    }
    
    
    struct Edge{
        int next;
        int to;
    };
    Edge edge[maxn];
    int head[maxn];
    int cnt;
    
    void addEdge(int u,int v){
        edge[++cnt].next = head[u];
        edge[cnt].to = v;
        head[u] = cnt;
    }
    int vis[maxn];
    int instack[maxn];
    stack<int> s;
    
    int ans = inf;
    bool dfs(int u){
        if(!instack[u] && !vis[u]){
            bool sign = false;
            instack[u] = 1;
            vis[u] = 1;
            s.push(u);
            for(int i=head[u];i;i=edge[i].next){
                sign |= dfs(edge[i].to);
                // if(sign)    return sign;
            }
            return sign;
        }else{ 
            if(s.empty()){  return false;}
            int to = s.top();
            int idx = 0;
            while(to!=u){
                s.pop();
                idx++;
                if(s.empty()){
                    return false;
                }
                to = s.top();
            }
            ans = min(ans,idx+1);
            return true;
        }
    }
    int main(){
        n = input();
        int to;
        FOR(i,n){
            to = input();
            addEdge(i,to);
        }
        FOR(i,n){
            if(!vis[i]){
                dfs(i);
                while(!s.empty())   s.pop();
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    

    所有节点只被访问一次即可每次memset(vis)结果TLE了QAQ,其实这道题还有更简单的写法,不过纯属练手了.

    题目
    前向星博客

  • 相关阅读:
    从句分析
    artDialog ( v 6.0.2 ) content 参数引入页面 html 内容
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 11 盛最多水的容器
    Java实现 LeetCode 11 盛最多水的容器
  • 原文地址:https://www.cnblogs.com/xxrlz/p/11234272.html
Copyright © 2011-2022 走看看