POJ 3660 Cow Contest
題目鏈接:vjudge傳送門
題目大意:
給定n個數,並且給定m組任意兩個數之間的關係,例如4個數,a>b,d>c,b>c,
若將四個數的大小排序,能確定排名的有幾數
具體思路:
若一個數能確定有多少個數大於它,以及多少個數小於他,那麼就可以確定該數的排名
因此可以建立正、反向圖,求出每個數的出度和入度,最後相加判斷總度是否爲n-1,是則說明能確定排名
用floyd也可以做,若一個數與其它所有的數都有關係(大於或小於),則說明該數能確定排名
用floyd剛好可以通過更新求出兩兩之間的關係
具體代碼:
//Floyd
#include<iostream>
#include<cstdio>
using namespace std;
const int N = 105;
const int INF = 1e9;
int maps[N][N];
int d[N];
int n, m;
void init()
{
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
maps[i][j] = 0; //初始化各點都沒關係
}
void floyd()
{
for(int k=1;k<=n;k++) //floyd算法
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
//a>b,b>c所以a>c 或 a<b,b<c所以a<c
if ((maps[i][k] == 1 && maps[k][j] == 1) || (maps[i][k] == 2 && maps[k][j] == 2))
maps[i][j] = maps[i][k];
}
}
}
int getAns() //掃描有多少個點滿足與其它點都有關係
{
int sum = 0;
for (int i = 1; i <= n; i++)
{
int flag = 1;
for (int j = 1; j <= n && flag; j++)
{
if (i != j && maps[i][j] == 0)
flag = 0; //表示存在一個點與i點沒關係
}
if (flag)sum++;
}
return sum;
}
int main()
{
cin >> n >> m;
init();
for (int j = 1; j <= m; j++)
{
int a, b;
cin >> a >> b;
maps[a][b] = 1; //表示大於關係
maps[b][a] = 2; //表示小於關係
}
floyd();
int ans = getAns();
cout << ans << endl;
return 0;
}