题目:
http://poj.org/problem?id=3275
分析:
如果要对n个数排序,需要知道任意两个数的大小关系,即n*(n-1)/2对关系;
现在知道m条边(a>b),由此可以确定知道了多少对大小关系(假设为sum对);
则答案为n*(n-1)/2 - sum;
如何知道任意两对是否已经知道了大小关系?
很容易想到Floyd,可是O(n^3)会超时,这里用邻接表优化;
需要注意,只是优化了常数,仍然可能超时!
代码:
#include <cstdio>
#include <vector>
using namespace std;
const int tmax=1002;
int n,m,ans;
bool f[tmax][tmax];
vector<int> in[tmax],out[tmax];
int main()
{
scanf("%d%d",&n,&m);
int i,j,k,a,b;
for(i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
f[a][b]=true;
in[b].push_back(a);
out[a].push_back(b);
}
for(k=1;k<=n;k++)
for(i=0;i<in[k].size();i++)
for(j=0;j<out[k].size();j++)
if(f[in[k][i]][out[k][j]]==false)
{
f[in[k][i]][out[k][j]]=true;
in[out[k][j]].push_back(in[k][i]);
out[in[k][i]].push_back(out[k][j]);
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
ans+=f[i][j];
printf("%d",n*(n-1)/2-ans);
return 0;
}