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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章