您的位置:首页 > 其它

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

2013-03-06 20:57 323 查看
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

18
0
18 0
0
0
11 0
0
0
0
0
0
5 0
0
0
0
0
0
0
2 0


样例输出1

16



限制

各个测试点1s

这一题和1023几乎一样

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

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

评测成绩(VIJOS)



/*http://blog.csdn.net/jiangzh7
By 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

;
int number,belong
,dfstime;
int now
,low
;
bool hash
,inst
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: