[USACO5.3]校园网Network of Schools
[USACO5.3]校园网Network of Schools
\(Tarjan\)板子+特判
不是很懂这个数据范围为什么是\(10^2\)害的我一直在想什么\(O(n^3)\)、\(O(n^4)\)的算法…………结果似乎是个\(O(n^2)\)的……
先\(Tarjan\)缩点;
-
子任务A:输出入度为零的点的个数;
-
子任务B:如果原图强联通输出0,否则输出\(max(入度0的点的个数,出度0的点的个数)\);
code:
#include<bits/stdc++.h>
using namespace std;
const int N=105,INF=0x3f3f3f3f;
inline int read()
{
char c=getchar();int x=0;
for(;!isdigit(c);c=getchar());
for(;isdigit(c);c=getchar())
x=x*10+c-'0';
return x;
}
int n;
vector<int> GG[N];
int DFN[N],ts,COL[N],LOW[N],colcnt,INDEG[N],OUDEG[N];
bool in[N];
stack <int> S;
void Tarjan(int u)
{
LOW[u]=DFN[u]=++ts;
S.push(u);
in[u]=1;
for(int i=0;i<GG[u].size();i++)
{
int v=GG[u][i];
if(DFN[v]==0)
{
Tarjan(v);
LOW[u]=min(LOW[u],LOW[v]);
}
else if(in[v])
{
LOW[u]=min(LOW[u],DFN[v]);
}
}
if(DFN[u]==LOW[u])
{
++colcnt;
while(!S.empty())
{
int x=S.top();
S.pop();
in[x]=0;
COL[x]=colcnt;
if(x==u)break;
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
while(1)
{
int v=read();
if(v==0)break;
GG[i].push_back(v);
}
}
for(int i=1;i<=n;i++)if(DFN[i]==0)Tarjan(i);
for(int i=1;i<=n;i++)
{
for(int j=0;j<GG[i].size();j++)
{
int u=i,v=GG[i][j];
if(COL[u]!=COL[v])
{
INDEG[COL[v]]++;
OUDEG[COL[u]]++;
}
}
}
int res1=0,res2=0;
for(int i=1;i<=colcnt;i++)
{
if(INDEG[i]==0)res1++;
if(OUDEG[i]==0)res2++;
}
cout<<res1<<endl;
if(colcnt==1)cout<<'0';
else cout<<max(res1,res2);
return 0;
}
本文来自博客园,作者:miyasaka,转载请注明原文链接:https://www.cnblogs.com/kion/p/11839685.html