zoj 2500 || poj 1975 Median Weight Bead

之所以划到最短路这里面。。。是因为用到floyd了。。

 

给你一些数的关系,输出不能成为中间数的数的个数。

 

我的做法是,对正图,转置图进行两次floyd即可(其实一次也可以,不过反正数据不大。。)。然后算每个点那行1的个数,大于等于(n+1)/2即不可能成为中间数。

 

如果是中间数,那么比它大的不能超过 n/2 ,比它小的也不能超过n/2。

 

其实转置图可以用先遍历列再遍历行得到。。我感觉用转置图更直观哈~

 

#include <stdio.h> #include <stdlib.h> #include <iostream> #include <string.h> using namespace std; int map[110][110]; int com[110][110]; int flag[110]; int main() { int ncases,n,m,i,j,k,ans,from,to; scanf("%d",&ncases); while( ncases-- ) { memset(map,0,sizeof(map)); memset(com,0,sizeof(com)); memset(flag,0,sizeof(flag)); scanf("%d%d",&n,&m); while( m-- ) { scanf("%d%d",&from,&to); map[from][to] = 1; com[to][from] = 1; } for(i=1; i<=n; i++) for(k=1; k<=n; k++) for(j=1; j<=n; j++) if( map[k][i] && map[i][j] ) map[k][j] = 1; for(i=1; i<=n; i++) { ans = 0; for(k=1; k<=n; k++) if( map[i][k] == 1 ) ans++; if( ans >= (n+1)/2 ) flag[i] = 1; } for(i=1; i<=n; i++) for(k=1; k<=n; k++) for(j=1; j<=n; j++) if( com[k][i] && com[i][j] ) com[k][j] = 1; for(i=1; i<=n; i++) { ans = 0; for(k=1; k<=n; k++) if( com[i][k] == 1 ) ans++; if( ans >= (n+1)/2 ) flag[i] = 1; } ans = 0; for(i=1; i<=n; i++) if( flag[i] ) ans++; printf("%d/n",ans); } return 0; }  

你可能感兴趣的:(zoj 2500 || poj 1975 Median Weight Bead)