[Tarjin三连发]poj1236 poj2168 poj 2553

http://poj.org/problem?id=1236

http://poj.org/problem?id=2168

 http://poj.org/problem?id=2553

 我想说tarjin不是很好写,我因为写错了targin WA了好几次。这两道题目是裸tarjin(求强联通分量),然后记录到id数组,就是缩点,不必建立新图,直接遍历所有边,然后计算出来出入度,刚开始的时候我卡在了最后,因为会了tarjin之后思路有的,但是通过出入度找到答案还是有点难度,而且有trick,所以一定要考虑全面,不过最重要的是学会算法,我的blog写的并不是很全面,很多时候是给自己看的,不过没关系,相信我的代码能有一定参考吧。。就算没人看也没关系。坚持努力吧。。

2168:

 

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<string>
#include<bitset>
#include<queue>
#include<vector>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#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 vv(a) vector<a>
#define vi vv(int)
#define vl vv(ll)
#define vb vv(bool)
//count distance 不能用哦,已经定义了。
using namespace std;
typedef long long ll;
template<class T>
void inline maxi(T &a,T &b){
    a=max(a,b);
}
template<class T>
void inline mini(T &a,T &b){
    a=min(a,b);
}
void shownum(int n,int m){
    rep(i,n,m){
        cout<<setw(6)<<i;
    }
    cout<<endl;
}
template<class T,class P>
void fill(T &a,P v){
    int n=SIZE(a)-1;
    re0(i,n)
        a[i]=v;
}
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=+1;
const int maxint=2147483647;
vi G,next,dest;
vi timee,id,low;
vi scc_num,out_num;
int n,m,tim;
set<pair<int,int> >sett;
stack<int> ss;
vb instack;
void addd(int a,int b){
    next.push_back(G[a]);
    G[a]=SIZE(next)-1;
    dest.push_back(b);
}
void init(){
    G.assign(n+1,-1);
    tim=0;
    sett.clear();
    while(!ss.empty())ss.pop();
    timee.assign(n+1,0);
    instack.assign(n+1,false);
    low.assign(n+1,0);
    id.assign(n+1,0);
    scc_num.assign(n+1,0);
    out_num.assign(n+1,0);
    re1(u,m){
        int a,b;
        scanf("%d%d",&a,&b);
        addd(a,b);
    }
}
void targin(int s){
    ss.push(s);
    instack[s]=true;
    timee[s]=low[s]=++tim;
    for(int i=G[s];i!=-1;i=next[i]){
        int v=dest[i];
        if(!timee[v]){
            targin(v);
            mini(low[s],low[v]);
        }else if(instack[v])
            mini(low[s],timee[v]);
    }
    if(low[s]==timee[s]){
        while(true){
            int t = ss.top();
            instack[t]=false;
            id[t]=s;
            scc_num[s]++;
            ss.pop();
            if(t==s)
                break;
        }
    }
}
void mmain(){
    while(~scanf("%d%d",&n,&m)){
        init();
        re1(u,n){
            if(!timee[u])
                targin(u);
        }
        int cc=0,j=0;
        re1(u,n){
            for(int i=G[u];i!=-1;i=next[i]){
                int v=dest[i];
                pair<int,int> p = make_pair(id[u],id[v]);
                if(p.first!=p.second && sett.find(p) == sett.end()){
                    sett.insert(p);
                    out_num[p.first]++;
                }
            }
        }
        vb mark(n+1,false);
        re1(u,n){
            int p = id[u];
            if(!mark[p] && out_num[p]==0){
                cc++;
                j=id[u];
            }
            mark[p]=true;
        }
        if(cc==0)
            printf("%d\n",n);
        else if(cc==1)
            printf("%d\n",scc_num[j]);
        else
            puts("0");
    }
}
//#define codeforces CODEFORCES
#define codeforces_input CODEFORCES_FILE
#define MANY_TEST CODEFORCES_MANY_TEST
#define MANY_TESST 3
int main(){
#ifdef codeforces
    #ifdef codeforces_input
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    #ifdef MANY_TEST
    re1(wwwwwwwwwwwwwwwwwwwww,MANY_TESST)
        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>
#include<set>
#include<stack>
#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 vv(a) vector<a>
#define vi vv(int)
#define vl vv(ll)
#define vb vv(bool)
//count distance 不能用哦,已经定义了。
using namespace std;
typedef long long ll;
template<class T>
void inline maxi(T &a,T &b){
    a=max(a,b);
}
template<class T>
void inline mini(T &a,T &b){
    a=min(a,b);
}
void shownum(int n,int m){
    rep(i,n,m){
        cout<<setw(6)<<i;
    }
    cout<<endl;
}
template<class T,class P>
void fill(T &a,P v){
    int n=SIZE(a)-1;
    re0(i,n)
        a[i]=v;
}
template<class T,class P>
void fill(T *a,P v,int n){
    re0(i,n-1)
        a[i]=v;
}
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=100+1;
const int maxint=2147483647;
//graph
int G[maxnum];
vi next,dest,dist;
void addd(int a,int b,int v){
    next.push_back(G[a]);
    G[a]=SIZE(next)-1;
    dest.push_back(b);
    dist.push_back(v);
}
void initG(){
    next.clear();
    dest.clear();
    dist.clear();
    fill(G,-1,maxnum-1);
}
//end graph
//tarjin
int timee[maxnum],id[maxnum],low[maxnum],tim,sccn;
bool instack[maxnum];
stack<int> ss;
void tarjin(int s){
    ss.push(s);
    instack[s]=true;
    timee[s]=low[s]=++tim;
    for(int i=G[s];i!=-1;i=next[i]){
        int v = dest[i];
        if(!timee[v]){
            tarjin(v);
            mini(low[s],low[v]);
        }else if(instack[v])
            mini(low[s],timee[v]);
    }
    if(low[s]==timee[s]){
        sccn++;
        while(true){
            int t = ss.top();
            ss.pop();
            instack[t]=false;
            id[t]=s;
            if(t==s)
                break;
        }
    }
}
void initT(){
    fill(timee,0,maxnum-1);
    fill(id,0,maxnum-1);
    fill(low,0,maxnum-1);
    fill(instack,false,maxnum-1);
    tim=sccn=0;
    while(!ss.empty())ss.pop();
}
//end tarjin
int in[maxnum],out[maxnum];
int n;
bool mark[maxnum];
void init(){
    initG();
    initT();
    fill(in,0,maxnum-1);
    fill(out,0,maxnum-1);
    fill(mark,false,maxnum-1);
    re1(u,n){
        int t;
        while(~scanf("%d",&t)){
            if(t==0)
                break;
            addd(u,t,0);
        }
    }
}
void mmain(){
    while(~scanf("%d",&n)){
        init();
        re1(u,n)
            if(!timee[u])
                tarjin(u);
        set< pair<intint> > sett;
        re1(u,n){
            for(int i = G[u];i != -1;i = next[i]){
                int v = dest[i];
                pair<int,int> p = make_pair(id[u], id[v]);
                if(p.first!=p.second && sett.find(p)==sett.end()){
                    sett.insert(p);
                    out[p.first]++;
                    in[p.second]++;
                }
            }
        }
        int ansA=0;
        int ansB=0;
        /*
        shownum(1,n);
        show(id,1,n);
        show(out,1,n);
        show(in,1,n);
        
*/
        //cout<<"#"<<sccn<<endl;
        re1(u,n){
            int p = id[u];
            if(!mark[p]){
                if(!in[p]){
                    ansA++;
                }
                if(!out[p]){
                    ansB++;
                }
            }
            mark[p]=true;
        }
        cout<<ansA<<endl;
        if(sccn==1)
            cout<<0<<endl;
        else
            cout<<max(ansA,ansB)<<endl;
    }
}
//#define codeforces CODEFORCES
#define codeforces_input CODEFORCES_FILE
#define MANY_TEST CODEFORCES_MANY_TEST
#define MANY_TESST 3
int main(){
#ifdef codeforces
    #ifdef codeforces_input
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    #ifdef MANY_TEST
    re1(wwwwwwwwwwwwwwwwwwwww,MANY_TESST)
        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>
#include<set>
#include<stack>
#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 vv(a) vector<a>
#define vi vv(int)
#define vl vv(ll)
#define vb vv(bool)
//count distance 不能用哦,已经定义了。
using namespace std;
typedef long long ll;
template<class T>
void inline maxi(T &a,T &b){
    a=max(a,b);
}
template<class T>
void inline mini(T &a,T &b){
    a=min(a,b);
}
void shownum(int n,int m){
    rep(i,n,m){
        cout<<setw(6)<<i;
    }
    cout<<endl;
}
template<class T,class P>
void fill(T &a,P v){
    int n=SIZE(a)-1;
    re0(i,n)
        a[i]=v;
}
template<class T,class P>
void fill(T *a,P v,int n){
    re0(i,n-1)
        a[i]=v;
}
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=5000+1;
const int maxint=2147483647;
//graph
int G[maxnum];
vi next,dest,dist;
void addd(int a,int b,int v){
    next.push_back(G[a]);
    G[a]=SIZE(next)-1;
    dest.push_back(b);
    dist.push_back(v);
}
void initG(){
    next.clear();
    dest.clear();
    dist.clear();
    fill(G,-1,maxnum-1);
}
//end graph
//tarjin
int timee[maxnum],id[maxnum],low[maxnum],tim,sccn;
bool instack[maxnum];
vi scc[maxnum];
stack<int> ss;
void tarjin(int s){
    ss.push(s);
    instack[s]=true;
    timee[s]=low[s]=++tim;
    for(int i=G[s];i!=-1;i=next[i]){
        int v = dest[i];
        if(!timee[v]){
            tarjin(v);
            mini(low[s],low[v]);
        }else if(instack[v])
            mini(low[s],timee[v]);
    }
    if(low[s]==timee[s]){
        sccn++;
        while(true){
            int t = ss.top();
            ss.pop();
            instack[t]=false;
            id[t]=s;
            scc[s].push_back(t);
            if(t==s)
                break;
        }
    }
}
void initT(){
    re0(u,maxnum-1)
        scc[u].clear();
    fill(timee,0,maxnum-1);
    fill(id,0,maxnum-1);
    fill(low,0,maxnum-1);
    fill(instack,false,maxnum-1);
    tim=sccn=0;
    while(!ss.empty())ss.pop();
}
//end tarjin
int in[maxnum],out[maxnum];
int n;
bool mark[maxnum];
void init(){
    initG();
    initT();
    fill(in,0,maxnum-1);
    fill(out,0,maxnum-1);
    fill(mark,false,maxnum-1);
    int m;
    scanf("%d",&m);
    re1(u,m){
        int a,b;
        scanf("%d%d",&a,&b);
        addd(a,b,0);
    }
}
void mmain(){
    while(~scanf("%d",&n)){
        if(n==0)
            break;
        init();
        re1(u,n)
            if(!timee[u])
                tarjin(u);
        set< pair<intint> > sett;
        re1(u,n){
            for(int i = G[u];i != -1;i = next[i]){
                int v = dest[i];
                pair<int,int> p = make_pair(id[u], id[v]);
                if(p.first!=p.second && sett.find(p)==sett.end()){
                    sett.insert(p);
                    out[p.first]++;
                    in[p.second]++;
                }
            }
        }
        int ansA=0;
        int ansB=0;
        /*
        shownum(1,n);
        show(id,1,n);
        show(out,1,n);
        show(in,1,n);
        
*/
        //cout<<"#"<<sccn<<endl;
        
        vi ans;
        re1(u,n){
            int p = id[u];
            if(!mark[p]){
                if(!out[p]){
                    re0(u,SIZE(scc[p])-1)
                        ans.push_back(scc[p][u]);
                }
            }
            mark[p]=true;
        }
        sort(ans.begin(),ans.end());
        re0(u,SIZE(ans)-1)
            cout<<ans[u]<<' ';
        cout<<endl;
    }
}
//#define codeforces CODEFORCES
#define codeforces_input CODEFORCES_FILE
#define MANY_TEST CODEFORCES_MANY_TEST
#define MANY_TESST 3
int main(){
#ifdef codeforces
    #ifdef codeforces_input
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    #ifdef MANY_TEST
    re1(wwwwwwwwwwwwwwwwwwwww,MANY_TESST)
        mmain();
    return 0;
    #endif
#endif
    mmain();

posted @ 2013-01-03 22:11  GGGin  阅读(234)  评论(0编辑  收藏  举报