【强连通】Victoria的舞会2 -- Vijos 1022,1023

来源:互联网 发布:淘宝客地推海报 编辑:程序博客网 时间:2024/05/20 05:57

Vijos   ---   P1022/1033 Victoria的舞会2
未递交

描述

 Victoria是一位颇有成就的艺术家,他因油画作品《我爱北京天安门》闻名于世界。现在,他为了报答帮助他的同行们,准备开一个舞会。

  Victoria准备邀请n个已经确定的人,可是问题来了:
  这n个人每一个人都有一个小花名册,名册里面写着他所愿意交流的人的名字。比如说在A的人名单里写了B,那么表示A愿意与B交流;但是B的名单里不见的有A,也就是说B不见的想与A交流。但是如果A愿意与B交流,B愿意与C交流,那么A一定愿意与C交流。也就是说交流有传递性。

  Victoria觉得需要将这n个人分为m组,要求每一组的任何一人都愿意与组内其他人交流。并求出一种方案以确定m的最小值是多少。

  注意:自己的名单里面不会有自己的名字。

格式

输入格式

第一行一个数n。接下来n行,每i+1行表示编号为i的人的小花名册名单,名单以0结束。1<=n<=200。

输出格式

一个数,m。

样例1

样例输入1

18018 00011 0000005 00000002 0

样例输出1

16

限制

各个测试点1s







这一题和1023几乎一样


任何两个人都可以互相交流,也就是任何两个点都在一个强连通里面


那么题意就很明显了,就是求出所有强连通,然后统计强连通个数即可


评测成绩(VIJOS)



/*http://blog.csdn.net/jiangzh7By Jiangzh*/#include<cstdio>#include<cstring>#include<stack>using namespace std;const int N=200+10;#define min(a,b) ((a)<(b)?(a):(b))#define max(a,b) ((a)>(b)?(a):(b))int n;int map[N][N];int number,belong[N],dfstime;int now[N],low[N];bool hash[N],inst[N];stack<int> st;void dfs(int x){now[x]=low[x]=++dfstime;hash[x]=true;st.push(x);inst[x]=true;for(int i=1;i<=n;i++) if(map[x][i]){if(!hash[i]){dfs(i);low[x]=min(low[x],low[i]);}else if(inst[i]) low[x]=min(low[x],now[i]);}if(low[x]==now[x]){while(!st.empty()){int u=st.top();st.pop();inst[u]=false;belong[u]=number;if(u==x) break;}number++;}}void tarjan(){for(int i=1;i<=n;i++) if(!hash[i]) dfs(i);if(!st.empty()){while(!st.empty()){int u=st.top();st.pop();belong[u]=number;}number++;}//for(int i=1;i<=n;i++) printf("%d ",belong[i]);}int main(){freopen("vijos1022.in","r",stdin);freopen("vijos1022.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;i++){int x;while(scanf("%d",&x)==1&&x) map[i][x]=1;}tarjan();printf("%d\n",number);return 0;}