hdu

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 }
原文地址:https://www.cnblogs.com/nowandforever/p/4544761.html