P1726 上白泽慧音

P1726 上白泽慧音

题目描述

在幻想乡,上白泽慧音是以知识渊博闻名的老师。春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄。因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点。

人间之里由 \(N\) 个村庄(编号为 \(1\cdots N\))和 \(M\) 条道路组成,道路分为两种一种为单向通行的,一种为双向通行的,分别用 \(1\)\(2\) 来标记。如果存在由村庄 \(A\) 到达村庄 \(B\) 的通路,那么我们认为可以从村庄 \(A\) 到达村庄 \(B\),记为 \((A,B)\)。当 \((A,B)\)\((B,A)\) 同时满足时,我们认为 \(A,B\) 是绝对连通的,记为 \(\langle A,B\rangle\)。绝对连通区域是指一个村庄的集合,在这个集合中任意两个村庄 \(X,Y\) 都满足 \(\langle X,Y\rangle\)。现在你的任务是,找出最大的绝对连通区域,并将这个绝对连通区域的村庄按编号依次输出。若存在两个最大的,输出字典序最小的,比如当存在 \(1,3,4\)\(2,5,6\) 这两个最大连通区域时,输出的是 \(1,3,4\)

输入格式

第一行共两个正整数 \(N,M\)

\(2\) 行至第 \(M+1\) 行,每行有三个正整数 \(a,b,t\)。若 \(t = 1\) 则表示存在从村庄 \(a\)\(b\) 的单向道路,若 \(t = 2\) 表示村庄 \(a,b\) 之间存在双向通行的道路。保证每条道路只出现一次。

输出格式

第一行输出 \(1\) 个整数,表示最大的绝对连通区域包含的村庄个数。

第二行输出若干个整数,依次输出最大的绝对连通区域所包含的村庄编号。

输入输出样例 #1

输入 #1

5 5
1 2 1
1 3 2
2 4 2
5 1 2
3 5 1

输出 #1

3
1 3 5

说明/提示

  • 对于 \(60\%\) 的数据,\(1\le N \le 200\),且 \(0\le M \le 10^4\)
  • 对于 \(100\%\) 的数据,\(1\le N \le 5\times 10^3\),且 \(0\le M \le 5\times 10^4\)
    这道题要注意每个连通量进入数组时不是按字典序,所以要对数组进行排序
#include<iostream>
#include<vector>
#include<stack>
#include<algorithm>
#define int long long
using namespace std;
const int N=1e5+5;
vector<int>v[N];
vector<int>ans[N];
int t=0;
int cnt=0;
int MAX=-1;
int low[N],dfsn[N],vis[N];
int n,m;
stack<int>s;
void dfs(int x){
    low[x]=dfsn[x]=++t;
    vis[x]=1;
    s.push(x);
    for(int i=0;i<v[x].size();i++){
        int y=v[x][i];
        if(!dfsn[y]){
            dfs(y);
            low[x]=min(low[x],low[y]);
        }
        else if(vis[y])low[x]=min(low[x],dfsn[y]);
    }
    if(low[x]==dfsn[x]){
        cnt++;
        while(s.top()!=x){
            vis[s.top()]=0;
            ans[cnt].push_back(s.top());
            s.pop();
        }
        vis[s.top()]=0;
        ans[cnt].push_back(s.top());
        s.pop();
        MAX=max(MAX,(long long )ans[cnt].size());
    }
}
signed main(){
    cin>>n>>m;
    while(m--){
        int p,a,b;
        cin>>a>>b>>p;
        if(p==1)v[a].push_back(b);
        if(p==2)v[a].push_back(b),v[b].push_back(a);
    }
    for(int i=1;i<=n;i++)if(!dfsn[i])dfs(i);
    for(int i=cnt;i>=1;i--){
        if(ans[i].size()==MAX){
            sort(ans[i].begin(),ans[i].begin()+ans[i].size());
            cout<<MAX<<endl;
            for(int j=0;j<ans[i].size();j++){
                cout<<ans[i][j]<<" ";
            }
            break;
        }
    }
    return 0;
}
posted @ 2025-03-13 21:56  郭轩均  阅读(12)  评论(0)    收藏  举报