hdu 6109 数据分割(并查集+set合并)

来源:互联网 发布:免费赚qq币软件 编辑:程序博客网 时间:2024/06/05 11:49

思路:

如果是相等,则看作一个集合,如果不等,则将两个集合连边。

在判断的时候,如果相等的集合中操作是0,就不对;

如果不等的集合操作是1,就不对

#include <algorithm>#include <cstring>#include <set>using namespace std;const int maxn=100005;set<int> g[maxn];int n,m;int a[maxn],b[maxn],c[maxn],fa[maxn];int anst,ans[maxn];int find(int x){    if(fa[x]!=x)        fa[x]=find(fa[x]);    return fa[x];}void init(){    for(int i=1;i<maxn;i++)        g[i].clear(),fa[i]=i;} int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)        scanf("%d%d%d",&a[i],&b[i],&c[i]);    init();    set<int>::iterator it;    for(int i=1;i<=n;i++)    {        int u=find(a[i]);        int v=find(b[i]);        if(c[i])        {            if(u==v)                continue;            else if(g[u].find(v)!=g[u].end())            {                init();                ans[++anst]=i;             }            else            {                for(it=g[v].begin();it!=g[v].end();++it)                {                    g[u].insert(*it);                    g[*it].erase(v);                    g[*it].insert(u);                }                g[v].clear();                fa[v]=u;            }        }        else        {            if(u!=v)            {                g[u].insert(v);                g[v].insert(u);            }            else            {                ans[++anst]=i;                init();            }        }    }    printf("%d\n",anst);    for(int i=1;i<=anst;i++)        printf("%d\n",ans[i]-ans[i-1]);    return 0;}


原创粉丝点击