P2746 [USACO5.3] 校园网Network of Schools
>>> 去看 极值 度数 rd==0 cd==0 连起来就是环 -> max(rd==0 sum, cd==0 sum)
>>> 每一对点 只能算出 缩点 rd cd ==0 的情况,
#include<cstdio> #include<bits/stdc++.h> using namespace std; const int N=105,M=2e4+5; stack<int> st; int n; int head[N],tot=0,dfn[N],low[N],num=0,co[N],col=0; struct EDGE { int to,nxt; } e[M]; void add(int u,int v) { e[++tot].to=v; e[tot].nxt=head[u]; head[u]=tot; } void Tarjan(int u) { dfn[u]=low[u]=++num; st.push(u); for(int i=head[u];i;i=e[i].nxt) { int v=e[i].to; if(dfn[v]==0) { Tarjan(v); low[u]=min(low[u],low[v]);// } else if(co[v]==0) { low[u]=min(low[u],dfn[v]);// } } if(low[u]==dfn[u])// { co[u]=++col; while(st.top()!=u) { co[st.top()]=col; st.pop(); } st.pop(); } } int ans1,ans2,vis[N][N]={0}; void count() { for(int i=1;i<=n;i++) { for(int j=head[i];j;j=e[j].nxt) { if(co[e[j].to]!=co[i])//&&vis[i][e[j].to]==0) { //vis[i][e[j].to]=1; vis[0][co[e[j].to]]++;// rd vis[co[i]][0]++;//cd } } } } int main() { cin>>n; for(int i=1;i<=n;i++) { int x; while(scanf("%d",&x)&&x) add(i,x); } for(int i=1;i<=n;i++) if(dfn[i]==0) Tarjan(i); count(); for(int i=1;i<=col;i++)// if col==1 -> 1 { ans1+=(vis[0][i]==0); ans2+=(vis[i][0]==0); } cout<<ans1<<endl<<((col==1)? 0:max(ans1,ans2))<<endl; return 0; }

浙公网安备 33010602011771号