洛谷P1726 上白泽慧音

求完强联通分量以后本来准备写一个自定义的比较函数或者暴力转成string类啥的来比较字典序.

后来仔细一想, 求强联通分量的时候不就是按照节点编号从小到大来的吗?

直接顺着扫一遍不就美滋滋了?

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <stack>
#include <vector>
using namespace std;
const int MAXN = 5e3 + 20;

int N, M;
vector<int> g[MAXN];

int dfn[MAXN], low[MAXN], col[MAXN];
vector<int> scc[MAXN]; int scccnt = 0;
stack<int> sta;
bool ins[MAXN];

void tarjan(int u)
{
    static int dfnclock = 0;
    dfn[u] = low[u] = ++dfnclock;
    sta.push(u); ins[u] = true;
    for(int i = 0; i < (int) g[u].size(); i++){
        int &v = g[u][i];
        if(!dfn[v]){
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(dfn[u] == low[u]){
        ++scccnt; int v;
        do{
            v = sta.top(); sta.pop();
            ins[v] = false;
            col[MAXN] = scccnt, scc[scccnt].push_back(v);
        }while(u != v);
    }
}

int main()
{
    cin>>N>>M;
    for(int i = 1, u, v, c; i <= M; i++){
        scanf("%d%d%d", &u, &v, &c);
        g[u].push_back(v);
        if(c == 2) g[v].push_back(u);
    }
    for(int i = 1; i <= N; i++) if(!dfn[i]) tarjan(i);
    int siz = 0, ans = 0;
    //for(int i = 1; i <= scccnt; i++) cout<<scc[scccnt].size()<<endl;
    for(int i = 1; i <= scccnt; i++) {
        if((int)scc[i].size() > siz) {
            siz = scc[i].size();
            ans = i;
        }
    }
    cout<<siz<<endl; sort(scc[ans].begin(), scc[ans].end());
    for(int i = 0; i < (int) scc[ans].size(); i++)
        cout<<scc[ans][i]<<" ";
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/wsmrxc/p/9329492.html