gym 101987 B Cosmetic Survey

题意

题意化简就是让你模拟出两两题面喜欢的人数之间的大小关系,连接单向边,然后定义了S(s,t)代表从s到t的所有路径中,最小边的最大值。并输出对于点x,满足其他所有点y使得S(x,y)>=S(y,x)并输出这些点 (n<=500)

题解

按题意模拟出建边后,对于该问题跑个Floryd,即可求出S数组,去转移式子S[x][y]=max(S[x][y],min(S[x][k],S[k][y]))

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
#include <set>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
 
using namespace std;
 
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
 
const int N=550,M=2e6+7;
 
int n,m;
int a[N][N];
int d[N][N];
int S[N][N];
bool vis[N];
bool VIS[N];
int num;
int Indeg[N],indeg[N];
vector<int>E[N];
queue<int>q;
vector<int >res;
void getd(int x,int y){
    int A=0,B=0;
    for(int i=1;i<=n;i++){
        if(a[i][x]==a[i][y]) continue;
        if(a[i][x]<a[i][y]){
            if(a[i][x]) A++;
            else B++;
        }
        else {
            if(a[i][y]) B++;
            else A++;
        }
    }
    d[x][y]=A;
    d[y][x]=B;
}
void dfs(int x){
    vis[x]=true;
    num++;
    for(auto & it:E[x]){
        indeg[it]++;
        if(vis[it]) continue;
        dfs(it);
    }
}
void getS(int x){
    memset(vis,false,sizeof(vis));
    memset(VIS,false,sizeof(VIS));
    for(int i=1;i<=m;i++) indeg[i]=0;
    num=0;
    dfs(x);
    cout<<indeg[x]<<endl;
    indeg[x]=0;
    while(q.size()) q.pop();
    q.push(x);
    int s=x;
    S[s][x]=550;
    while(q.size()){
        int x=q.front();
        VIS[x]=true;
        q.pop();
        for(auto &y:E[x]){
            S[s][y]=max(S[s][y],min(S[s][x],d[x][y]));
            indeg[y]--;
            if(indeg[y]==0){
                q.push(y);
            }
        }
    }
}
bool judge(int x){
    for(int i=1;i<=m;i++) {
        if(i==x) continue;
        if(S[x][i]<S[i][x]) return false;
    }
    return true;
}
int main(){
    //freopen(".txt","r",stdin);
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            scanf("%d",&a[i][j]);
        }
    }
    for(int i=1;i<=m;i++){
        for(int j=i+1;j<=m;j++){
            getd(i,j);
            if(d[i][j]>d[j][i]){
                E[i].push_back(j);
                S[i][j]=d[i][j];
            }
            else if(d[i][j]<d[j][i]){
                E[j].push_back(i);
                S[j][i]=d[j][i];
            }
        }
    }
//    for(int i=1;i<=m;i++){
//        for(int j=1;j<=m;j++) {
//            S[i][j]=d[i][j];
//        }
//    }
    for(int k=1;k<=m;k++){
        for(int i=1;i<=m;i++){
            for(int j=1;j<=m;j++){
                S[i][j]=max(S[i][j],min(S[i][k],S[k][j]));
            }
        }
    }
//    for(int i=1;i<=m;i++){
//        for(int j=1;j<=m;j++) cout<<S[i][j]<<' ';
//        cout<<endl;
//    }
//    for(int i=1;i<=m;i++){
//        getS(i);
//    }
    for(int i=1;i<=m;i++){
        if(judge(i)) res.push_back(i);
    }
    for(int i=0;i<res.size();i++){
        printf("%d",res[i]);
        if(i==(int)res.size()-1) puts("");
        else printf(" ");
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章