51Nod2670还原竞赛图思维+传递闭包
Posted hesorchen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51Nod2670还原竞赛图思维+传递闭包相关的知识,希望对你有一定的参考价值。
题目
一张完全无向图,给出每个点的出度,要对每条边定向,求可以互相到达的点对数量。保证答案存在且唯一。
求解
题目保证答案存在且唯一,那么就保证了 s u m a i = n ∗ ( n − 1 ) 2 sum_{a_i}=\\frac {n*(n-1)}{2} sumai=2n∗(n−1)。
需要注意的是,对某条边定向的时候,需要考虑,这样会不会导致后面的点的出度无法满足。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int out[N];
int mp[N][N];
bool vis[N][N];
int in[N];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> out[i];
for (int i = 1; i <= n; i++)
{
int tmp = out[i];
for (int j = 1; tmp && j <= n; j++)
{
if (i == j)
continue;
if (!vis[i][j] && (n - 1) - in[j] - out[j] > 0)
//保证这条边还没用过,并且用了也不会导致后面的边无法使用
{
in[j]++;
tmp--;
mp[i][j] = 1;
vis[i][j] = vis[j][i] = 1;
}
}
}
for (int i = 1; i <= n; i++)
mp[i][i] = 1;
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (mp[i][k] && mp[k][j])
mp[i][j] = 1;
int ans = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
ans += mp[i][j];
cout << ans << endl;
return 0;
}
以上是关于51Nod2670还原竞赛图思维+传递闭包的主要内容,如果未能解决你的问题,请参考以下文章