7-10 排座位

思路#

这题用并查集+set就可以过,题中说两个人不可能既是朋友,又是敌人的意思是数据中不会让两个人的关系既是朋友关系,又是敌人关系,但是如果两个人是敌人,但是有共同的朋友,也可以是朋友+敌人的关系。

最开始我只用set写的,但是错了,想用set模拟并查集,但是发现好像只有暴力具有正确性。

代码#

#include <bits/stdc++.h>
using namespace std;

int ans[105][105];
int pre[105];
set<int> st[105];

void init() {
    for (int i=0;i<105;i++) {
        pre[i]=i;
    }
}

inline int find(int x) {
    if (pre[x]==x) {
        return x;
    }
    return pre[x]=find(pre[x]);
}

void unions(int x,int y) {
    int fx=find(x);
    int fy=find(y);
    if (fx!=fy) {
        pre[fx]=fy;
    }
}

int getRel(int a,int b) {
    bool flag1=false;
    bool flag2=false;
    if (find(a)==find(b)) {
        flag1=true;
    }
    if (st[a].count(b)||st[b].count(a)) {
        flag2=true;
    }
    if (flag1&&!flag2) {
        return 1;
    }
    else if (!flag1&&!flag2) {
        return 2;
    }
    else if (flag1&&flag2) {
        return 3;
    }
    return 4;
}

int main()
{
    init();
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    int p1,p2,rel;
    while (m--){
        scanf("%d%d%d",&p1,&p2,&rel);
        if (rel==1) {
            unions(p1,p2);
        }
        else {
            st[p1].insert(p2);
            st[p2].insert(p1);
        }
    }
    for (int i=1;i<=n;i++) {
        for (int j=i+1;j<=n;j++) {
            ans[i][j]=getRel(i,j);
        }
    }
    while (k--) {
        scanf("%d%d",&p1,&p2);
        if (p1>p2) {
            swap(p1,p2);
        }
        if (ans[p1][p2]==1){
            printf("No problem
");
        }
        else if (ans[p1][p2]==2) {
            printf("OK
");
        }
        else if (ans[p1][p2]==3){
            printf("OK but...
");
        }
        else {
            printf("No way
");
        }
    }
    return 0;
}
/*
3 3 3
1 2 1
1 3 1
2 3 -1
1 3
2 3
1 2
*/

原文地址:https://www.cnblogs.com/xyqxyq/p/12317625.html