标签:rip sim with sample 去掉 amp enter ber case
3 3 3 1 2 2 3 3 1 3 3 1 2 2 3 1 3 6 6 1 2 2 3 3 1 4 5 5 6 6 4
Case 1: -1 Case 2: 1 Case 3: 15
#include <bits/stdc++.h> using namespace std; const int N=100000+5; int dfn[N],low[N],team[N],num[N],in[N],out[N]; bool instack[N]; int n,T,m,index,team_num; vector<int> mp[N]; stack<int> S; void Tarjan(int u) { low[u]=dfn[u]=++index; S.push(u); instack[u]=1; for(int i=0;i<mp[u].size();i++) { int v=mp[u][i]; if (!dfn[v]) { Tarjan(v); low[u]=min(low[u],low[v]); } else if (instack[v]) low[u]=min(low[u],dfn[v]); } if (dfn[u]==low[u]) { team_num++; while(1) { int v=S.top(); S.pop(); instack[v]=0; team[v]=team_num; // v点是第几组 num[team_num]++; //第i组的点个数 if (v==u) break; } } } void dfs() { memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(instack,0,sizeof(instack)); memset(team,0,sizeof(team)); memset(num,0,sizeof(num)); team_num=0; index=0; for(int i=1;i<=n;i++) if (!dfn[i]) Tarjan(i); } int main() { scanf("%d",&T); for(int cas=1;cas<=T;cas++) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) mp[i].clear(); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); mp[x].push_back(y); } dfs(); //缩点,求出各个组的点数 printf("Case %d: ",cas); for(int i=1;i<=team_num;i++) in[i]=out[i]=0; for(int i=1;i<=n;i++) for(int j=0;j<mp[i].size();j++) { if (team[i]!=team[mp[i][j]]) { in[team[mp[i][j]]]++; out[team[i]]++; } } //统计入度数和出度数 int minn=100000; for(int i=1;i<=team_num;i++) if (in[i]==0 || out[i]==0) minn=min(minn,num[i]); //求出入度=0或者出度=0的点数最小的组 if (team_num==1) printf("-1\n"); else printf("%lld\n",(long long)n*n-n-(long long)minn*(n-minn)-m); } return 0; }
HDU 4635 Strongly connected (Tarjan+一点数学分析)
标签:rip sim with sample 去掉 amp enter ber case
原文地址:http://www.cnblogs.com/stepping/p/7668360.html