POJ 3275 Ranking the Cows
题意: 有 n 头牛,知道了m 对牛之间的关系,问最少还需要知道多少对牛的关系才能确定所有牛之间的关系。
分析: n个节点,共有n*(n-1)/2个对应关系,要确定所有关系即确定这 n*(n-1)/2个对应关系, 对于已经给出的m个关系,用传递闭包求出已经确定的关系总数res,
对于剩下的n*(n-1)/2-total个关系,由传递闭包的性质知:如果节点i和节点j之间的关系不确定,那他们之间在原图中时相对独立的,而每次询问的答案又都是
不确定的,所以需要对于这些关系全部进行询问才能知道全序关系节点数比较多,在传递闭包的时候要用邻接表实现.
#include<stdio.h> #include<string.h> #include<vector> using namespace std; #define clr(x)memset(x,0,sizeof(x)) #define maxn 1005 int g[maxn][maxn]; int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { clr(g); int a,b; vector<int>from[maxn]; vector<int>to[maxn]; while(m--) { scanf("%d%d",&a,&b); g[a][b]=1; from[b].push_back(a); to[a].push_back(b); } int i,j,k; int u,v; for(k=1;k<=n;k++) for(i=0;i<from[k].size();i++) for(j=0;j<to[k].size();j++) { u=from[k][i]; v=to[k][j]; if(!g[u][v]) { g[u][v]=1; from[v].push_back(u); to[u].push_back(v); } } int res=0; for(i=1;i<=n;i++) for(j=1;j<=n;j++) { if(i==j) continue; if(g[i][j]) res++; } printf("%d\n",(n*(n-1)/2)-res); } return 0; }