Network of Schools
You are to write a program that computes the minimal number of schools that must receive a copy of the new software in order for the software to reach all schools in the network according to the agreement (Subtask A). As a further task, we want to ensure that by sending the copy of new software to an arbitrary school, this software will reach all schools in the network. To achieve this goal we may have to extend the lists of receivers by new members. Compute the minimal number of extensions that have to be made so that whatever school we send the new software to, it will reach all other schools (Subtask B). One extension means introducing one new member into the list of receivers of one school.
5 2 4 3 0 4 5 0 0 0 1 0Sample Output
12
注意編輯 數組開大點 WA了3次 才發現!!!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<queue>
#include<vector>
#include<stack>
#include<list>
#include<map>
#include<set>
using namespace std;
const int maxn = 200+5;
int Laxt[maxn],Next[maxn*200],To[maxn*200],cnt,n,m,ans1,ans2;
int times,dfn[maxn],low[maxn],scc[maxn],scc_cnt;
int stc[maxn],top,instc[maxn];
int rd[maxn],cd[maxn];
void add(int u,int v)
{
Next[++cnt]=Laxt[u];
Laxt[u]=cnt;
To[cnt]=v;
}
void init()
{
top=cnt=scc_cnt=ans1=ans2=0;
memset(Laxt,0,sizeof(Laxt));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(scc,0,sizeof(scc));
memset(stc,0,sizeof(stc));
memset(instc,0,sizeof(instc));
memset(rd,0,sizeof(rd));
memset(cd,0,sizeof(cd));
}
int dfs(int u)
{
dfn[u]=low[u]=++times;
stc[++top]=u;
instc[u]=1;
for(int i=Laxt[u]; i; i=Next[i])
{
int v=To[i];
if(!dfn[v])
{
dfs(v);
low[u]=min(low[u],low[v]);
}
else if(instc[v])
{
low[u]=min(low[u],low[v]);
}
}
if(dfn[u]==low[u])
{
scc_cnt++;
while(true)
{
int x=stc[top--];
scc[x]=scc_cnt;
instc[x]=0;
if(x==u) break;
}
}
}
void tarjan()
{
int i;
for(i=1; i<=n; i++)
if(!dfn[i]) dfs(i);
for(i=1; i<=n; i++)
for(int j=Laxt[i]; j ; j=Next[j])
{
int v=To[j];
if(scc[v]!=scc[i])
{
cd[scc[i]]++;
rd[scc[v]]++;
}
}
for(i=1; i<=scc_cnt; i++)
{
if(cd[i]==0) ans2++;
if(rd[i]==0) ans1++;
}
if(scc_cnt==1)
printf("1\n0\n");
else
printf("%d\n%d\n",ans1,max(ans1,ans2));
}
int main()
{
while(~scanf("%d",&n))
{
init();
for(int i=1; i<=n; i++)
{
while(scanf("%d",&m)&&m)
{
add(i,m);
}
}
tarjan();
}
}