POJ 3660 Cow Contest【傳遞閉包 Floyd變形】

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;
}
發佈了69 篇原創文章 · 獲贊 34 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章