Codeforces Goodbye 2014 problem B ACM解题报告(经典的并查集)

来源:互联网 发布:潜25淘宝哪个店是真的 编辑:程序博客网 时间:2024/05/22 05:22

这题对于大神来说简直水题,毕竟是B题,但是对于本渣渣来说确实是好题,开头暴力贪心,用了好多循环就是WA,死活过不了第15个test,后来经学长提醒用并查集秒杀之啊。

本题是某几个位置的数可以互相交换位置,交换后输出字典序最小的一组。。。

把可以互相交换的全部用并查集连通,然后把存在于同一个集合的数排序,再放回,这样就是轻松秒杀啊。

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int pre[305];int Find(int x){    int r=x;    while(pre[r]!=r)        r=pre[r];    int i=x,j;    while(pre[i]!=r)    {        j=pre[i];        pre[i]=r;        i=j;    }    return r;}void mix(int x, int y){    int fx=Find(x);    int fy=Find(y);    if(fy!=fx) pre[fy]=fx;}int main(){    int n;    int a[305],d[305];    char b[305][305];    scanf("%d",&n);    for(int i=1;i<=n;i++) pre[i]=i;    for(int i=1;i<=n;i++) scanf("%d",&a[i]);    for(int i=1;i<=n;i++)    {        getchar();        for(int j=1;j<=n;j++)        {            scanf("%c",&b[i][j]);            if(b[i][j]=='1') mix(i,j);        }    }    for(int i=1;i<=n;i++)    {        int count=0;        for(int j=1;j<=n;j++)        {            if(Find(j)==i)            {                d[count++]=a[j];            }        }        sort(d,d+count);        count=0;        for(int j=1;j<=n;j++)        {            if(Find(j)==i) a[j]=d[count++];        }    }    for(int i=1;i<=n;i++)    {        if(i!=n) printf("%d ",a[i]);        else printf("%d\n",a[i]);    }    return 0;}

0 0