[USACO08JAN]牛大赛Cow Contest

传送门:https://www.luogu.org/problemnew/show/P2419

这道题拿到之后想了很多种做法,贪心。。。。以及建树。。。然后。。。。从入度为零的点求最短路。。。。然鹅好像不行。。。。

这道题可以拿floyd做qww。又是一道考验大家是否理解Floyd的题。

floyed不仅能求任意两点的最短路,还能求一个点能否到另一个点。

这道题用了floyed算法的变化,用floyed算法判图的连通性,用f[i][j]判断从i到j联不联通。

f[i][j]=f[i][j]||(f[i][k]&&f[k][j])表示i到j联不联通,要么一开始i能到j,要么i能到k,k再能到j。

用floyed求出每个点与这个点的关系,只要这个点和其他n-1个点的关系都确定了,就能确定他的排名。

#define B cout << "BreakPoint" << endl;
#define O(x) cout << #x << " " << x << endl;
#define O_(x) cout << #x << " " << x << "  ";
#define Msz(x) cout << "Sizeof " << #x << " " << sizeof(x)/1024/1024 << " MB" << endl;
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#define N 105
using namespace std;
inline int read() {
    int s = 0,w = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9') {
        if(ch == '-')
            w = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') {
        s = s * 10 + ch - '0';
        ch = getchar();
    }
    return s * w;
}
int a,b,n,m,f[N][N];
void init(){
	n = read(),m = read();
	for(int i = 1;i <= m;i++){
		a = read(),b = read();
		f[a][b] = 1;
	}
	return ;
}
void floyd(){
	for(int k = 1;k <= n;k++)
		for(int i = 1;i <= n;i++)
			for(int j = 1;j <= n;j++){
				f[i][j] = f[i][j] || f[i][k] && f[k][j];
			}
	return ;
}
int ans;
void solve(){
	for(int i = 1;i <= n;i++){
		int sum = 1;
		for(int j = 1;j <= n;j++)
			if(i == j) continue;
			else
				sum = sum && (f[i][j] || f[j][i]);
			ans += sum;
	}
	printf("%d\n",ans);
	return ;
}
int main(){
	init();
	floyd();
	solve();
	return 0;
}

  

posted @ 2019-04-13 12:33  优秀的渣渣禹  阅读(195)  评论(0编辑  收藏  举报