您的位置:首页 > 其它

poj 1236 Network of Schools

2012-08-10 16:49 399 查看
题意:

给定一个有向图,求下面两个量:

1 :最少从几个点出发能遍历全图。

2 :最少加几条边能使原图强联通。
解法:

“最少从几个点出发能遍历全图”的点数是将原图缩点后入度为零的点的个数。

“最少加几条边能使原图强联通”的边数是将原图缩点后出度为零的点和入读为零的点中的最大值。
(注意强联通图的情况)

#include<iostream>
using namespace std;
const int MAXN =101;
int DFN[MAXN];
int LOW[MAXN];
int instack[MAXN];
int Stap[MAXN];
int Belong[MAXN];
bool in_num[MAXN];
bool out_num[MAXN];
bool map[MAXN][MAXN];
struct edge
{
int v,next;
}vetex[50001];
int head[MAXN];
int Stop,Bcnt,Dindex,N,k;
void add(int a,int b)
{
vetex[k].v = b;
vetex[k].next = head[a];
head[a] = k;k++;
}
void tarjan(int i)
{
int j;
DFN[i]=LOW[i]=++Dindex;
instack[i]=true;
Stap[++Stop]=i;
for (int k=head[i];k;k=vetex[k].next)
{
j=vetex[k].v;
if (!DFN[j])
{
tarjan(j);
if (LOW[j]<LOW[i])
LOW[i]=LOW[j];
}
else if (instack[j] && DFN[j]<LOW[i])
LOW[i]=DFN[j];
}
if (DFN[i]==LOW[i])
{
Bcnt++;
do
{
j=Stap[Stop--];
instack[j]=false;
Belong[j]=Bcnt;
}
while (j!=i);
}
}
void solve()
{
int i;
Stop=Bcnt=Dindex=0;
for (i=1;i<=N;i++)
if (!DFN[i])
tarjan(i);
}
int main()
{
while(cin>>N)
{
k=1;
memset(in_num,0,sizeof(in_num));
memset(out_num,0,sizeof(out_num));
memset(DFN,0,sizeof(DFN));
memset(head,false,sizeof(head));
for(int i=1;i!=N+1;i++)
{
int a;cin>>a;
while(a!=0)
{
add(i,a);
cin>>a;
}
}
solve();
if(Bcnt == 1)
{
cout<<1<<endl;
cout<<0<<endl;
continue;
}
//cout<<Bcnt<<endl;
for(int i=1;i!=N+1;i++)
{
int t = Belong[i];
for(int k=head[i];k;k=vetex[k].next)
{
if(t!=Belong[vetex[k].v])
{
out_num[Belong[vetex[k].v]] = true;
in_num[t] = true;
}
}
}
int in(0),out(0);
for(int i=1;i!=Bcnt+1;i++)
{
if(!in_num[i])
{
in++;
}
if(!out_num[i])
{
out++;
}
}
cout<<out<<endl;
cout<<((in>out)?in:out)<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: