http://acm.hdu.edu.cn/showproblem.php?pid=1704
遇到标记过的就dfs,把隐含的标记,最后计数需要注意。
1 #include <cstdio> 2 #include <cstring> 3 int n; 4 int vis[501][501]; 5 void dfs(int x,int y) 6 { 7 for(int i=1;i<=n;i++) 8 if(vis[y][i]) 9 { 10 vis[x][i]=1; 11 dfs(x,i); 12 } 13 } 14 int main() 15 { 16 // freopen("a.txt","r",stdin); 17 int t,m,a,b; 18 scanf("%d",&t); 19 while(t--) 20 { 21 memset(vis,0,sizeof(vis)); 22 scanf("%d%d",&n,&m); 23 for(int i=0;i<m;i++) 24 { 25 scanf("%d%d",&a,&b); 26 vis[a][b]=1; 27 } 28 for(int i=1;i<=n;i++) 29 for(int j=1;j<=n;j++) 30 if(vis[i][j]) 31 { 32 dfs(i,j); 33 } 34 int ans=0; 35 for(int i=1;i<=n;i++) 36 for(int j=i+1;j<=n;j++) 37 if(!vis[i][j]&&!vis[j][i]) ans++; 38 printf("%d ",ans); 39 } 40 return 0; 41 }
也可以用有向图传递闭包的方法。实质是一样的。
1 #include <cstdio> 2 #include <cstring> 3 int vis[501][501]; 4 5 int main() 6 { 7 // freopen("a.txt","r",stdin); 8 int t,n,m,a,b; 9 scanf("%d",&t); 10 while(t--) 11 { 12 memset(vis,0,sizeof(vis)); 13 scanf("%d%d",&n,&m); 14 for(int i=0;i<m;i++) 15 { 16 scanf("%d%d",&a,&b); 17 vis[a][b]=1; 18 } 19 for(int k=1;k<=n;k++) 20 for(int i=1;i<=n;i++) 21 if(vis[i][k]) 22 { 23 for(int j=1;j<=n;j++) 24 vis[i][j]=vis[i][j]||vis[k][j]; 25 } 26 int ans=0; 27 for(int i=1;i<=n;i++) 28 for(int j=i+1;j<=n;j++) 29 if(!vis[i][j]&&!vis[j][i]) ans++; 30 printf("%d ",ans); 31 } 32 return 0; 33 }