洛谷 P1726 上白泽慧音 题解

一、题目:

洛谷原题

二、思路:

闲扯句废话,从今开始我要刷洛谷试炼场了!
那么言归正传,这道题明显是个有向图的tarjan好嘛。注意按照字典序输出,其他也没什么。

三、代码:

//自认为很优美的代码:
#include
#include
#include
#include

using namespace std;

template<class Type>
inline void read(Type &num){
    Type x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    num=f*x;
}

const int maxn=5005,maxm=50005;

int n,m;

int head[maxn],tot;

int dfn[maxn],low[maxn],num,bl[maxn],stack[maxn],top,cnt;
bool ins[maxn];

vector<int>scc[maxn];

struct Edge{
    int y,next;
    Edge(){}
    Edge(int _y,int _next):y(_y),next(_next){}
}e[maxm<<1];

inline void connect(int x,int y){
    e[++tot]=Edge(y,head[x]);
    head[x]=tot;
}

inline void Tarjan(int x){
    dfn[x]=low[x]=++num;
    stack[++top]=x;ins[x]=true;
    for(register int i=head[x];i;i=e[i].next){
        int y=e[i].y;
        if(!dfn[y]){
            Tarjan(y);
            low[x]=min(low[x],low[y]);
        }
        else if(ins[y])low[x]=min(low[x],low[y]);
    }
    if(dfn[x]==low[x]){
        ++cnt;int y;
        do{
            y=stack[top--];ins[y]=false;
            bl[y]=cnt;scc[cnt].push_back(y);
        }while(x!=y);
    }
}

int main(){
    read(n);read(m);
    for(register int i=1;i<=m;++i){
        int x,y,t;
        read(x);read(y);read(t);
        if(t==1){
            connect(x,y);
        }
        else if(t==2){
            connect(x,y);connect(y,x);
        }
    }
    for(register int i=1;i<=n;++i){
        if(!dfn[i])Tarjan(i);
    }
    int tmp=0,pos=0;
    for(register int i=1;i<=cnt;++i){
        // tmp=max(tmp,scc[i].size());
        if(scc[i].size()>tmp){tmp=scc[i].size();pos=i;}
    }
    printf("%d\n",tmp);
    sort(scc[pos].begin(),scc[pos].end());//不加这句会“听取WA声一片”。
    for(register int i=0;i<scc[pos].size();++i)printf("%d ",scc[pos][i]);
    puts("");
    // system("pause");
    return 0;
}

你可能感兴趣的:(考验美术?——图论)