poj 2553强连通+缩点

/*先吐槽下,刚开始没看懂题,以为只能是一个连通图0T0
 题意:给你一个有向图,求G图中从v可达的所有点w,也都可以达到v,这样的v称为sink.求这样的v.
 解;求强连通+缩点。求所有出度为0的点即为要求的点。
 注意:可能有多个联通分支。
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N  5100
struct node {
 int u,v,w,next;
}bian[N*N*2];
int head[N],yong,cnt,vis[N],stac[N],top,index,n,low[N],dfn[N],belong[N],outdegree[N];
void addedge(int u,int v) {
    bian[yong].u=u;
    bian[yong].v=v;
    bian[yong].next=head[u];
    head[u]=yong++;
}
int cmp(const void *a,const void *b) {
return *(int *)a-*(int *)b;
}
void init() {
yong=0;
memset(head,-1,sizeof(head));
top=0;cnt=0;
index=0;
memset(vis,0,sizeof(vis));
memset(stac,0,sizeof(stac));
memset(outdegree,0,sizeof(outdegree));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(belong,0,sizeof(belong));
}
int Min(int a,int b) {
return a>b?b:a;
}
void tarjan(int u) {
  low[u]=dfn[u]=++index;
  stac[++top]=u;
  vis[u]=1;
  int i;
  for(i=head[u];i!=-1;i=bian[i].next) {
    int v=bian[i].v;
    if(!dfn[v]) {
        tarjan(v);
        low[u]=Min(low[u],low[v]);
    }
    else
    if(vis[v])
        low[u]=Min(low[u],dfn[v]);
  }
  if(low[u]==dfn[u]){
    cnt++;
    int t;
    do {
        t=stac[top--];
        belong[t]=cnt;
        vis[t]=0;
    }while(t!=u);
  }
}
int main() {
   int m,i,a,b,j;
   while(scanf("%d",&n),n) {
        init();
    scanf("%d",&m);
    while(m--) {
        scanf("%d%d",&a,&b);
        addedge(a,b);
    }
    for(i=1;i<=n;i++)//缩点
    if(!dfn[i])
    tarjan(i);
    //printf("%d\n",cnt);
    for(i=0;i<yong;i++) {
    a=bian[i].u;
    b=bian[i].v;
    if(belong[a]!=belong[b])
        outdegree[belong[a]]++;
    }
    top=0;
    for(i=1;i<=cnt;i++)
        if(outdegree[i]==0) {//找出度为0的点
     for(j=1;j<=n;j++)
        if(belong[j]==i)
        stac[top++]=j;
        }
        qsort(stac,top,sizeof(int),cmp);//排序
     for(i=0;i<top-1;i++)//
        printf("%d ",stac[i]);
     printf("%d\n",stac[top-1]);
   }
return 0;
}

poj 2553强连通+缩点

时间: 2024-10-10 14:24:09

poj 2553强连通+缩点的相关文章

NYOJ-120 校园网络 &amp;&amp;POJ 1236 (强连通缩点targan算法)

链接:click here 题意: 校园网络 时间限制:3000 ms  |  内存限制:65535 KB 难度:5 描述 南阳理工学院共有M个系,分别编号1~M,其中各个系之间达成有一定的协议,如果某系有新软件可用时,该系将允许一些其它的系复制并使用该软件.但该允许关系是单向的,即:A系允许B系使用A的软件时,B未必一定允许A使用B的软件. 现在,请你写一个程序,根据各个系之间达成的协议情况,计算出最少需要添加多少个两系之间的这种允许关系,才能使任何一个系有软件使用的时候,其它所有系也都有软件

POJ 2553 taarjan缩点+度数

The Bottom of a Graph Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 8904   Accepted: 3689 Description We will use the following (standard) definitions from graph theory. Let V be a nonempty and finite set, its elements being called ver

POJ 2553 The Bottom of a Graph(强连通分量)

POJ 2553 The Bottom of a Graph 题目链接 题意:给定一个有向图,求出度为0的强连通分量 思路:缩点搞就可以 代码: #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <stack> using namespace std; const int N = 5005; int n, m; vector&l

POJ 2553 The Bottom of a Graph (强连通分量)

题目地址:POJ 2553 题目意思不好理解.题意是:G图中从v可达的全部点w,也都能够达到v,这种v称为sink.然后升序输出全部的sink. 对于一个强连通分量来说,全部的点都符合这一条件,可是假设这个分量还连接其它分量的话,则肯定都不是sink.所以仅仅须要找出度为0的强连通分量就可以. 代码例如以下: #include <iostream> #include <string.h> #include <math.h> #include <queue>

POJ 2553 The Bottom of a Graph(Tarjan,强连通分量)

解题思路: 本题要求 求出所有满足"自己可达的顶点都能到达自己"的顶点个数,并从小到大输出. 利用Tarjan算法求出强连通分量,统计每个强连通分量的出度,出度为0的强连通分量内的顶点即为所求顶点. #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <cmath

Poj 2186 Popular Cows(Tarjan 强连通缩点)

传送门:Poj 2186 题意:给你n头牛,m种关系,A牛认为B牛是popular的,B牛认为C牛是popular的,则A也认为C是popular的,问最终有几头被所有牛认为是popular的牛 题解:强连通缩点基础题(虽然我Tarjan和缩点都是对的,但是最终讨论判断的时候写垮了(写了3天....还不是你懒!!!!过年划水这么多天缩点后找出度为零的点个数.然后讨论是否有这样子的点,如果没有则全都是(整个都是强连通图),如果只有一个,那么那个强连通分量所含的牛的个数就是所求解,如果有多个那么都是

poj 2553 The Bottom of a Graph 【强连通图中出度为0点】

题目:poj 2553 The Bottom of a Graph 题意:大概题意是给出一个有向图,求强连通缩点以后出度为0的点. 分析:入门题目,先强连通缩点,然后表示出度为0的,枚举输出即可. #include <cstdio> #include <vector> #include <iostream> #include <stack> #include <cstring> using namespace std; const int N =

POJ 2553 The Bottom of a Graph TarJan算法题解

本题分两步: 1 使用Tarjan算法求所有最大子强连通图,并且标志出来 2 然后遍历这些节点看是否有出射的边,没有的顶点所在的子强连通图的所有点,都是解集. Tarjan算法就是模板算法了. 这里使用一个数组和一个标识号,就可以记录这个顶点是属于哪个子强连通图的了. 然后使用DFS递归搜索所有点及其边,如果有边的另一个顶点不属于本子强连通图,那么就说明有出射的边. 有难度的题目: #include <stdio.h> #include <stdlib.h> #include &l

POJ2762 Going from u to v or from v to u?(强连通缩点+拓扑排序)

Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15196   Accepted: 4013 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors