[邻接表DFS]最长链和最大环

http://poj.org/problem?id=3895 (最大环)

http://www.codeforces.com/problemset/problem/116/C (最长链)

两道题,都用的邻接表,这个邻接表上次也说过了,figo教的,next为边内存池吧。。下标和dest与dist对应。最长链就是DFS找到最长的,最深的(DFS每一个点,但是我DFS学的不好,不知道有没有更好的方法,找最大环的时候我刚开始还是用DFS每个点的方法,但是GG了,所以我就研究了一下别人的代码,后来发现不用DFS每一个顶点,只要出现了,DFS条件!vis[i]不满足的情况就说明有环出现,所以只要记录一下子就行了。哦也。

 

 

 

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include< string>
#include<bitset>
#include<queue>
#include<vector>
#include< string>
#include<cmath>
#include<map>
#define rep(i,n,m) for(int i=(n);i<=(m);++i)
#define re1(i,n) rep(i,1,n)
#define re0(i,n) rep(i,0,n)
#define RE(a) ((a)*(a))
#define SIZE(a) (int((a).size()))
#define vi vector<int>
#define vl vector<ll>
#define vs vector<string>
// time count distance 不能用哦,已经定义了。
using  namespace std;
typedef  long  long ll;
template< class T>
void inline maxi(T &a, const T &b){
    a=max(a,b);
}
template< class T>
void inline mini(T &a, const T &b){
    a=min(a,b);
}
template< class T>
void show( const T &a, int n, int m){
    rep(i,n,m){
        cout<<setw( 6)<<a[i];
    }
    cout<<endl;
}
void shownum( int n, int m){
    rep(i,n,m){
        cout<<setw( 6)<<i;
    }
    cout<<endl;
}
template< class T>
void show(T *a[ 10], int n, int m){
    re0(i,n){
        re0(j,m)
            cout<<a[i]<< '   ';
        cout<<endl;
    }
}
template< class T, class P>
void fill(T &a,P v){
    re0(i,SIZE(a)- 1)
        a[i]=v;
}
const  int maxnum= 2000+ 1;
const  int maxint= 2147483647;
vi G,next,dist,dest,path,d;
vector< bool> vis;
void addD( int  from, int to, int dis= 1){
    next.push_back(G[ from]);
    G[ from]=SIZE(next)- 1;
    dest.push_back(to);
    dist.push_back(dis);
}
int timee,n;
void init(){
    G.assign(maxnum,- 1);
    scanf( " %d ",&n);
    re1(u,n){
         int a;
        scanf( " %d ",&a);
         if(a!=- 1)
            addD(u,a);
    }
    vis.assign(maxnum, false);
    path.assign(maxnum,- 1);
    d.assign(maxnum,- 1);
}
void dfs( int s){
    vis[s]= true;
    timee++;
    d[s]=timee;
     for( int i=G[s];i!=- 1;i=next[i]){
         int v=dest[i];
         if(!vis[v]){
            path[v]=s;
            dfs(v);
        }
    }
}
/*
int findp(int from,int to){
    if(to==-1)
        return -1;
    if(from!=path[to])
        return findp(from,path[to]);
}
void print_path(int from,int to){
    if(to==from){
        cout<<from<<endl;
    }else if(path[to]==-1){
        cout<<"GG"<<endl;
    }else{
        print_path(from,path[to]);
        cout<<to<<endl;
    }
}
*/
int mmain(){
    init();
     /*
    shownum(0,n);
    show(G,0,n);
    show(next,0,SIZE(next)-1);
    show(dest,0,SIZE(next)-1);
    
*/
     int ans=- 1;
    re1(u,n){
        timee= 0;
        fill(vis, false);
         if(!vis[u])
            dfs(u);
        maxi(ans,timee);
    }
    cout<<ans<<endl;
     /*
    if(findp(5,6)!=-1){
        print_path(5,6);
    }else
        cout<<"GG"<<endl;
    
*/
}
#define codeforces CODEFORCES
// #define INPUT CODEFORCES_FILE
// #define MANY_TEST CODEFORCES_MANY_TEST
int main(){
#ifdef codeforces
    #ifdef INPUT
    freopen( " input.txt ", " r ",stdin);
    freopen( " output.txt ", " w ",stdout);
     #endif
    #ifdef MANY_TEST
    re1(wwwwwwwwwwwwwwwwwwwww, 3)
        mmain();
     return  0;
     #endif
#endif
    mmain();

}

 

#include<iostream>

#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include< string>
#include<bitset>
#include<queue>
#include<vector>
#include< string>
#include<cmath>
#include<map>
#define rep(i,n,m) for(int i=(n);i<=(m);++i)
#define re1(i,n) rep(i,1,n)
#define re0(i,n) rep(i,0,n)
#define re(a) ((a)*(a))
#define SIZE(a) (int((a).size()))
#define v(a) vector<a>
#define vi v(int)
#define vl v(ll)
#define vb v(bool)
// count distance 不能用哦,已经定义了。
using  namespace std;
typedef  long  long ll;
template< class T>
void inline maxi(T &a, const T &b){
    a=max(a,b);
}
template< class T>
void inline mini(T &a, const T &b){
    a=min(a,b);
}
template< class t, class p>
void fill(t &a,p v){
     int n=SIZE(a)- 1;
    re0(i,n)
        a[i]=v;
}
void shownum( int n, int m){
    rep(i,n,m){
        cout<<setw( 6)<<i;
    }
    cout<<endl;
}
template< class t>
void show(t &a, int n, int m){
    rep(i,n,m){
        cout<<setw( 6)<<a[i];
    }
    cout<<endl;
}
template< class t>
void show(t *a[ 10], int n, int m){
    re0(i,n){
        re0(j,m)
            cout<<a[i]<< '   ';
        cout<<endl;
    }
}
const  int maxnum= 4444+ 1;
const  int maxint= 2147483647;
int n,m,ans;
vi G,next,dest,d,timee;
vb vis;
void addd( int  from, int to){
    next.push_back(G[ from]);
    G[ from]=SIZE(next)- 1;
    dest.push_back(to);
}
void init(){
    scanf( " %d%d ",&n,&m);
    G.assign(n+ 1,- 1);
    vis.assign(n+ 1, false);
    d.assign(n+ 1, 1);
    timee.assign(n+ 1, 0);
    re1(u,m){
         int a,b;
        scanf( " %d%d ",&a,&b);
        addd(a,b);
        addd(b,a);
    }
}
void findl( int s, int time){
    vis[s]= true;
    timee[s]=time;
     for( int i=G[s];i!=- 1;i=next[i]){
         int v=dest[i];
         if(!vis[v]){
            findl(v,time+ 1);
        } else{
            maxi(ans,timee[v]-timee[s]);
        }
    }
}
int mmain(){
     int tcase;
    scanf( " %d ",&tcase);
    re1(uuuuuuuuuuuuuuu,tcase){
        init();
        ans=- 1;
         /*
        shownum(0,size(next)-1);
        show(g,0,n);
        show(next,0,size(next)-1);
        show(dest,0,size(next)-1);
        
*/
        re1(u,n){
             if(!vis[u])
                findl(u, 1);
        }
        printf( " %d\n ",ans+ 1);
    }
}
// #define codeforces codeforces
// #define input codeforces_file
// #define many_test codeforces_many_test
int main(){
#ifdef codeforces
    #ifdef input
    freopen( " input.txt ", " r ",stdin);
    freopen( " output.txt ", " w ",stdout);
     #endif
    #ifdef many_test
    re1(wwwwwwwwwwwwwwwwwwwww, 3)
        mmain();
     return  0;
     #endif
#endif
    mmain();

转载于:https://www.cnblogs.com/gggin/archive/2012/12/27/2836577.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值