poj3660(floyd最短路)

题目链接:https://vjudge.net/problem/POJ-3660

题意:给出一个有向图,n个结点,每个结点的权值为[1,n]中的一个独特数字,m条边,如果存在边a->b,说明a的权值大于b,问能确定多少个点的权值。

思路:

  用邻接矩阵存边,a[i][j]=1表示存在边i->j,然后跑floyd。

  松弛操作为:如果a[i][j]==0&&a[i][k]==1&&a[k][j]==1,那么更新a[i][j]=1。

  一个结点的权值能够确认的充要条件是它和其它n-1个点的关系确认。

AC code:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

const int maxn=105;
int ans,n,m,a[maxn][maxn];

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;++i){
        int u,v;
        scanf("%d%d",&u,&v);
        a[u][v]=1;
    }
    for(int k=1;k<=n;++k)
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
                if(!a[i][j]&&a[i][k]&&a[k][j])
                    a[i][j]=1;
    for(int i=1;i<=n;++i){
        int num=0;
        for(int j=1;j<=n;++j)
            if(a[i][j]||a[j][i]) ++num;
        if(num==n-1) ++ans;
    }
    printf("%d
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/FrankChen831X/p/11859288.html