在交际网络中,给定若干个元素和若干对二元关系,且关系具有传递性。通过传递性推导出尽量多的元素之间的关系的问题被成为传递闭包
建立邻接矩阵
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;
}