codeforces gym #101987B- Cosmetic Survey(floyd)

题目链接:

https://codeforces.com/gym/101987/my

题意:

顶点数为$n$,边数为$m$

求出每个点对$(a,b)$,$a$到$b$的最小路径的最大值

数据范围:

$1leq n leq 500$

$1leq m leq 1250000$

分析: 

直接floyd处理

当时想的是用边来放缩S值,既然可以用边放缩,那么就可以用点放缩

AC代码:

#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
using namespace std;
const int maxn=500+7;
int S[maxn][maxn];
int ma[maxn][maxn];
int sk[maxn],top,cnt,n,m;
int main(){
    scanf("%d %d",&m,&n);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            scanf("%d",&ma[i][j]);
            if(ma[i][j]==0)ma[i][j]=1e7;
        }
    for(int i=1;i<=m;i++){
        for(int j=i+1;j<=m;j++){
            int a=0,b=0;
            for(int k=1;k<=n;k++){
                if(ma[k][i]<ma[k][j])a++;
                else if(ma[k][i]>ma[k][j])b++;
            }
            if(a>b)S[i][j]=a;
            else if(b>a)S[j][i]=b;
        }
    }
    for(int k=1;k<=m;k++){
        for(int i=1;i<=m;i++){
            for(int j=1;j<=m;j++){
                if(S[i][k]==0||S[k][j]==0)continue;
                S[i][j]=max(S[i][j],min(S[i][k],S[k][j]));
            }
        }
    }
    for(int i=1;i<=m;i++){
        int fla=1;
        for(int j=1;j<=m;j++){
            if(i==j)continue;
            if(S[i][j]<S[j][i]){
                fla=0;
                break;
            }
        }
        if(fla)sk[++top]=i;
    }
    for(int i=1;i<=top;i++){
        printf("%d",sk[i]);
        if(i==top)printf("
");
        else printf(" ");
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/carcar/p/11598221.html