POJ-2513 Colored Sticks 无向图欧拉通路判定+字符串hash

题意:给定许多根棍子,这些棍子两头有不同的颜色,问是否能够存在这样一中组合方式使得所有的棍子首尾相连。

解法:这题使用map处理字符串超时了,所以自己写了一个插值取模的字符串hash。只要判定图是否连通和度为奇数是否大于2个即可,不可能出现奇数个度为奇数的点。

代码如下:

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <map>
#include <string>
#include <vector>
using std::vector;

typedef unsigned long long int64;
const int MOD = 250007;
const int64 T = 37;
char sa[15], sb[15];
int deg[500005];
int set[500005];
int head[250010];
int64 _pow[15];

vector<int>v;

struct Edge {
    int tag, next;
    int64 key;
}e[500005];
int idx, tag;


int find(int x) {
    return set[x] = x == set[x] ? x : find(set[x]);    
}

void merge(int a, int b) {
    set[a] = b;
}

void insert(int64 key, int tg) {
    int pos = key % MOD;
    e[idx].key = key;
    e[idx].tag = tg;
    e[idx].next = head[pos];
    head[pos] = idx++;
}

int64 getkey(char str[]) {
    int64 key = 0;
    int len = strlen(str);
    for (int i = 0; i < len; ++i) {
        key += (str[i]-'a') * _pow[i];
    }
    return key;
}

void hash(char str[]) {
    int64 key = getkey(str);
    insert(key, tag++);
}

int get(char str[]) {
    int64 key = getkey(str);
    int pos = key % MOD;
    for (int i = head[pos]; i != -1; i = e[i].next) {
        if (e[i].key == key) {
            return e[i].tag;
        }
    }
    return -1;
}

int main() {
    int ok = 0;
    for (int i = 0; i < 500000; ++i) {
        set[i] = i;
    }
    _pow[0] = 1;
    for (int i = 1; i <= 10; ++i) {
        _pow[i] = T * _pow[i-1];
    }
    memset(head, 0xff, sizeof (head));
    while (scanf("%s %s", sa, sb) != EOF) {
        if (get(sa) == -1) {
            hash(sa);
        } 
        if (get(sb) == -1) {
            hash(sb);
        }
        int a = get(sa), b = get(sb);
        ++deg[a], ++deg[b];
        merge(find(a), find(b));
    }
    for (int i = 0; i < tag; ++i) {
        if (set[i] == i) {
            ++ok;
        }
        if (deg[i] & 1) {
            v.push_back(i);
        }
    }
    if (ok != 1 && ok) {
        puts("Impossible");
        return 0;
    } else if (v.size() > 2){
        puts("Impossible");
    } else {
        puts("Possible");
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/Lyush/archive/2013/03/27/2983910.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值