#include <stdio.h>
#include <string.h>
#include <cstdio>
using namespace std;
const int N = 1002;
bool path[N][N];
bool path0[N][N];
int m, n;
void floyd()
{
int i, j, k;
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
for(k = 1; k <= n; k++)
if(path[j][i] && path[i][k]) path[j][k] = path0[j][k] = true;
}
int main()
{
int i, j, a, b, res;
while(~scanf("%d%d", &n, &m))
{
res = 0;
memset(path, false, sizeof(path));
memset(path0, false, sizeof(path0));
for(i = 1; i <= m; i++)
{
scanf("%d%d", &a, &b);
path[a][b] = true;
}
floyd();
for(i = 1; i <= n; i++)
for(j = i + 1; j <= n; j++)
if(path0[i][j] || path0[j][i]) res++;
printf("%d\n", n * (n - 1) / 2 - res);
}
return 0;
#include <string.h>
#include <cstdio>
using namespace std;
const int N = 1002;
bool path[N][N];
bool path0[N][N];
int m, n;
void floyd()
{
int i, j, k;
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
for(k = 1; k <= n; k++)
if(path[j][i] && path[i][k]) path[j][k] = path0[j][k] = true;
}
int main()
{
int i, j, a, b, res;
while(~scanf("%d%d", &n, &m))
{
res = 0;
memset(path, false, sizeof(path));
memset(path0, false, sizeof(path0));
for(i = 1; i <= m; i++)
{
scanf("%d%d", &a, &b);
path[a][b] = true;
}
floyd();
for(i = 1; i <= n; i++)
for(j = i + 1; j <= n; j++)
if(path0[i][j] || path0[j][i]) res++;
printf("%d\n", n * (n - 1) / 2 - res);
}
return 0;
}
心得:本题虽然搞出来了,但还没有完全理解floyd,留着当成问题吧