【CODE[VS]】2822 爱在心中 强连通分量

5 篇文章 0 订阅
4 篇文章 0 订阅

题目传送门
其实这题还是挺水的,强联通分量的正解也是比较好想的,直接上tarjan。
对于题目的第一问,只要求节点数大于1的强联通分量个数就好了。
对于题目的第二问,只要求节点数大于1且出度为0的强联通分量中的所有节点编号就行了。
小提示:这题有两个要注意的地方:

  1. 第二问的答案要求该强联通分量的节点数大于1。(我就是在这里WA了好多次,以后一定要注意读题,汗……)
  2. 还是第二问,在输出每个强联通分量中的节点编号之前记得排序。(数据坑……)

代码打的比较乱,将就着看看吧……
附上AC代码:

#include <cstdio>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;

stack <int> s;
vector <int> map[1010],scc[1010];
int n,m,x,y,d[1010],t[1010],b[1010],sy[1010],g,ans,size,cd[1010],rd[1010];
bool bo;

void so(int x){
    b[x]=1,t[x]=d[x]=++size,s.push(x);
    for (int i=0; i<map[x].size(); ++i)
        if (!d[map[x][i]]) so(map[x][i]),t[x]=min(t[x],t[map[x][i]]);
            else if (b[map[x][i]]) t[x]=min(t[x],d[map[x][i]]);
    if (t[x]==d[x]){
        ++g;int p,sum=0;
        while (!s.empty()){
            p=s.top();++sum,s.pop(),b[x]=0,sy[p]=g,scc[g].push_back(p);
            if (p==x) break;
        }
        sort(scc[g].begin(),scc[g].end());
        if (sum>1) ++ans;
    }
    return;
}

int main(void){
    scanf("%d%d",&n,&m);
    for (int i=1; i<=m; ++i) scanf("%d%d",&x,&y),map[x].push_back(y);
    for (int i=1; i<=n; ++i) if (!d[i]) so(i);
    printf("%d\n",ans);
    for (int i=1; i<=n; ++i)
        for (int j=0; j<map[i].size(); ++j)
            if (sy[i]!=sy[map[i][j]]) {
                cd[sy[i]]+=scc[sy[map[i][j]]].size();
                rd[sy[map[i][j]]]+=scc[sy[i]].size();
            }
    ans=0;
    for (int i=1; i<=g; ++i)
        if (!cd[i]){
            if (ans) {bo=1;break;}
            if (scc[i].size()==1) continue;
            ans=i;
        }
    if (!ans||bo) printf("-1");
    else for (int i=0; i<scc[ans].size(); ++i) printf("%d ",scc[ans][i]);
    return 0;
}

写在最后:果然还是要好好读题(学好语文),没有看懂题目,一切都是扯淡……

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值