zoukankan      html  css  js  c++  java
  • [題解]luogu_P1333瑞瑞的木棍(并查集/圖論)

    是一道歐拉路的題竟然沒看出來......


    把每種顏色看成一個點,每根木棍看成一個邊,即相同顏色在圖中接好合併成了一個點,

    問題轉化為了求是否存在歐拉路

    如果用map會超時,所以可以用字典樹實現離散化/哈希,unordered_map需要c++11

    注意判斷圖是否聯通,用并查集即可

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<unordered_map>
    using namespace std;
    const int maxn=250010*2;//點數 
    int x,y,cnt,n;char s[15];
    int deg[maxn];
    int fa[maxn];
    int find(int x){
        while(x!=fa[x])x=fa[x]=fa[fa[x]];
        return x;
    }
    bool unionn(int x,int y){
        x=find(x),y=find(y);
        if(x==y)return 0;
        fa[x]=y;return 1;
    }
    //字典樹 
    int nod=1,root=1;
    struct node{
        int son[26],num;
    }t[maxn*2];
    int ask(char *s){
        int k=root;char c;
        for(int i=0;s[i];i++){
            c=s[i]-'a';
            if(!t[k].son[c])t[k].son[c]=++nod;//動態開點 
            k=t[k].son[c];
        }
        if(!t[k].num)t[k].num=++n;
        return t[k].num;
    }
    //unordered_map<string,int>m;
    //int ask(char *s){
    //    return m[s]?m[s]:m[s]=++n;
    //}
    int main(){
        for(int i=1;i<=maxn;i++)fa[i]=i;
        while(~scanf("%s",s)){
            x=ask(s);
            scanf("%s",s);
            y=ask(s);
            if(unionn(x,y))++cnt;
            ++deg[x],++deg[y];
        }
        if(cnt<n-1){printf("Impossible");return 0;}//判聯通
        int tot=0;//記錄奇點個數 
        for(int i=1;i<=n;i++){
            if(deg[i]&1)tot++;
            if(tot>2){printf("Impossible");return 0;}
        }
        printf("Possible");
    }
  • 相关阅读:
    超好看的UI配色网站汇总~
    JS获取非行内样式
    最近看到的一些不错前端面试题目
    指令
    $filter $watch
    学习学习学习
    Mongoose by时间查询
    AngularJs 学习 笔记 4 foreach
    AngularJs 学习 笔记 3
    AngularJs 学习 笔记 2
  • 原文地址:https://www.cnblogs.com/superminivan/p/10724982.html
Copyright © 2011-2022 走看看