floyd与传递闭包

在交际网络中,给定若干个元素和若干对二元关系,且关系具有传递性。通过传递性推导出尽量多的元素之间的关系的问题被成为传递闭包
建立邻接矩阵 d d d d i , j = 1 d_{i,j}=1 di,j=1 表示 i i i j j j 有关系, d i , j = 0 d_{i,j}=0 di,j=0 表示 i i i j j j 没有关系。特别的, d i , i d_{i,i} di,i 始终为 1 1 1。使用 f l o y d floyd floyd 算法可以解决传递闭包问题:

ll n, m;
bool d[maxn][maxn];
void work()
{
	cin >> n >> m;
	for(int i = 1; i <= n; ++i) d[i][i] = 1;
	for(int i = 1; i <= m; ++i){
		int x, y;cin >> x >> y;
		d[x][y] = d[y][x] = 1;
	}
	for(int k = 1; k <= n; ++k)
		for(int i = 1; i <= n; ++i)
			for(int j = 1; j <= n; ++j)
				d[i][j] |= d[i][k] & d[k][j];
}

P2419 [USACO08JAN]Cow Contest S
思路:
有向传递闭包问题
d [ i ] [ j ] d[i][j] d[i][j] 表示 i i i 可以打败 j j j
如果 i i i 能打败 k k k 并且 k k k 能打败 j j j,那么 i i i 也能打败 j j j
一个牛的编号可以确定当且仅当它和其他所有牛的关系都可以确定,即要么可以打败 j j j 或者被 j j j 打败
code:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define mem(x, d) memset(x, d, sizeof(x))
#define eps 1e-6
using namespace std;
const int maxn = 5e2 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
bool d[maxn][maxn];
void work()
{
	cin >> n >> m;
	for(int i = 1; i <= n; ++i) d[i][i] = 1;
	for(int i = 1; i <= m; ++i){
		int x, y;cin >> x >> y;
		d[x][y] = 1;
	}
	for(int k = 1; k <= n; ++k)
		for(int i = 1; i <= n; ++i)
			for(int j = 1; j <= n; ++j)
				d[i][j] |= d[i][k] & d[k][j];
	int ans = 0;
	for(int i = 1; i <= n; ++i){
		int x = 1;
		for(int j = 1; j <= n; ++j) if(i != j)
			x &= (d[i][j] | d[j][i]);
		ans += x;
	}
	cout << ans;
}

int main()
{
	ios::sync_with_stdio(0);
//	int TT;cin>>TT;while(TT--)
	work();
	return 0;
}

343. 排序
code:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define mem(x, d) memset(x, d, sizeof(x))
#define eps 1e-6
using namespace std;
const int maxn = 5e2 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
bool d[maxn][maxn];
string s[maxn];

void work()
{
	mem(d, 0);
	for(int i = 1; i <= m; ++i) cin >> s[i];
	for(int l = 1; l <= m; ++l){
		int x = s[l][0] - 'A' + 1, y = s[l][2] - 'A' + 1;
		d[x][y] = 1;
		for(int k = 1; k <= n; ++k)
			for(int i = 1; i <= n; ++i)
				for(int j = 1; j <= n; ++j)
					d[i][j] |= d[i][k] & d[k][j];
		int ans = 0;
		int q[30] = {0};
		for(int i = 1; i <= n; ++i){
			int x = 1, cnt = 0;
			for(int j = 1; j <= n; ++j) if(i != j)
			{
				x &= (d[i][j] | d[j][i]);
				if(d[i][j]) ++cnt;
				if(d[i][j] && d[j][i] || d[j][j]){
					cout << "Inconsistency found after " << l << " relations.\n";
					return;
				}
			}
			ans += x;
			q[cnt + 1] = i;
		}
		if(ans == n){
			cout << "Sorted sequence determined after " << l << " relations: ";
			for(int i = n; i >= 1; --i) cout << char(q[i]+'A'-1);cout << ".\n";
			return;
		}
	}
	cout << "Sorted sequence cannot be determined.\n";
}

int main()
{
	ios::sync_with_stdio(0);
//	int TT;cin>>TT;while(TT--)
	while(cin >> n >> m && n + m)
	work();
	return 0;
}

344. 观光之旅

345. 牛站

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值