Title

P8014 [COCI2013-2014#4] SUMO 题解

一道简单的并查集......

题目传送门

在洛谷博客内观看


 

大体思路:

其实我一开始也没有想到这是并查集的题目,还想了半天,一看题解,恍然大悟——原来这么简单!

主要思想就是从第一场开始,让 PK 的两人尽可能不在一队,这样就能保证同一队的 PK 尽可能地靠后了。

也就是说,如果第 i 场时,两人还没有关系(还没标记为同一队),那么就将互相放到敌队中去;如果两人已经是同一队的关系了,那么输出 i(找到答案了),直接结束程序就好了。

思想很简单,但确实难想到(对我这个小蒟蒻来说 QAQ)。


 

代码:

#include<iostream>
using namespace std;
int f[100001]={0};
int d[100001]={0};
int find(int x){
    if(f[x]==x) return x;
    return f[x]=find(f[x]);
}
void hb(int x,int y){
    f[x]=y;
}
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++) f[i]=i; //初始化 father 数组。
    for(int i=1;i<=m;i++){
        int x,y;
        cin>>x;
        cin>>y;
        int xx=find(x); //这里我提前查找了,能为后面节约一点点时间(虽然就一点点)。
        int yy=find(y);
        if(xx==yy){ //判断是否找到答案,即正在 PK 的两人是否已经是同一队。
            cout<<i<<endl;
            break;
        }
        if(find(d[x])!=yy&&d[x]!=0){ //d[x]!=0 是判断是否还是初始状态。
            hb(find(d[x]),yy);
        }
        if(find(d[y])!=xx&&d[y]!=0){
            hb(find(d[y]),xx);
        }
        d[x]=yy; //标记为敌人。
        d[y]=xx;
    }
    return 0;
} 

总结:

其实这道题还有一点点贪心的成分在,不知道大家有没有感觉到,就是让正在 PK 的两人尽可能不在一队这一操作......

 

posted @ 2022-08-03 23:08  Zilljy  阅读(28)  评论(0编辑  收藏  举报