poj-2513-Colored Sticks-字典树trie / hash +并查集 欧拉回路
2016-01-17 22:20
531 查看
http://poj.org/problem?id=2513
..........一看到题。。试着用hash水一下。。wa
用map水一下TLE。。
好吧。。trie试一下。。。wa .wa .wa.....
好吧。。最后发现是自己傻逼了。。。
窝一开始犯了傻逼错误,以为 直接 计算颜色出现的种数。。。奇数个数的颜色为0或2 就 合法。。然而这只是必要条件.....不是充分条件...........
除了要奇数度数 为 0 或 2才能满足题目要求,还要【保证能联通】, (后来发现这个东西叫欧拉回路)
联通的话 用个并查集判一下联通即可。。。
于是分别用hash、trie水了一遍
以下是用trie字典树做的 425ms
//头文件
double eps=0.000001; const ull mod= 2000007; const int maxnode = 5000000+5 ; int fa[5000000]; int deg[5000000]; struct trie { int ch[maxnode][26]; int val[maxnode]; int sz; void init() { sz=1; val[0]=0; memset(ch[0],0,sizeof(ch[0])); } inline int idx(char c) {return c-'a';} void insert(char *s,int v) { int u=0,n=strlen(s),i; for (i=0;i<n;i++) { int c=idx(s[i]); if (!ch[u][c]) { memset(ch[sz],0,sizeof(ch[sz])); val[sz]=0; ch[u][c]=sz++; } u=ch[u][c]; } val[u]=v;//该单词出现一次 } int query(char *s) { int u=0,n=strlen(s),i; for (i=0;i<n;i++) { int c=idx(s[i]); if (!ch[u][c]) return 0; else u=ch[u][c]; } return val[u]; } }; int find(int x) { if (fa[x]==x) return x; else return fa[x]=find(fa[x]); } trie tp; int main() { tp.init(); int i=0; for (i=1;i<=5000000;i++) fa[i]=i; char ss[30]; int cnt=0; while(gets(ss)) { int len=strlen(ss); for (i=0;i<len;i++) { if (ss[i]==' ')break; } ss[i]=0; int x=tp.query(ss); int y=tp.query(ss+i+1); if (!x) tp.insert(ss,x=++cnt); if (!y) tp.insert(ss+i+1,y=++cnt); deg[x]++;deg[y]++; int fx= find(x); int fy=find(y); if (fx!=fy) fa[fx]=fy; } int one=0; for (i=1;i<=cnt;i++) { if (deg[i]%2) one++; } int flag=1; int k=find(1); for (i=1;i<=cnt;i++) {if (find(i)!=k) {flag=0;break;}} if (flag==1&&(one==2||one==0) ) printf("Possible\n"); else printf("Impossible\n"); return 0; }
以下是hash的代码
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
typedef unsigned __int64 ull;
const double pi=acos(-1.0);
double eps=0.000001;
int n;
inthash[273933+5];
const ull mod= 273933;
char ss[30];
int fa[273933+5];
ull gethash(char *s ,ull p)
{
ull tmp=0;
int i,len=strlen(s);
for (i=0;i<len;i++)
{
tmp=tmp*p+s[i];
}
return tmp;
}
int find(int x)
{
if (fa[x]==x)
return x;
else
return fa[x]=find(fa[x]);
}
int que[273933],que_ok=0;
int main()
{
int i=0;
for (i=1;i<=273933;i++)
fa[i]=i;
int ok=0;
while(gets(ss))
{
int len=strlen(ss);
for (i=0;i<len;i++)
{
if (ss[i]==' ')break;
}
ss[i]=0;
ull ret=gethash(ss+i+1,239);
int dd=ret%273933;
que[++que_ok]=dd;
hash[dd]++;
int tmpd=dd;
ret=gethash(ss,239);
dd=ret%273933;
que[++que_ok]=dd;
hash[dd]++;
int fx=find(dd);
int fy=find(tmpd);
if (fx!=fy)
fa[fx]=fy;
}
int one=0;
for (i=0;i<273933;i++)
{
if (hash[i]%2) one++;
}
int flag=1;
int head=find(que[1]);
for (i=1;i<=que_ok;i++)
{
if (find(que[i])!=head)
{flag=0;break;}
}
if (flag==1&&(one==0||one==2))
printf("Possible\n");
else
printf("Impossible\n");
return 0;
}
相关文章推荐
- 玩转objective-c
- 二分查找法-指针和数组表示-优化效率
- 空间金字塔方法表示图像
- 首届CCF软件能力认证试题第二题详解(窗口)
- php实现插入排序
- 再见,2015,你好,2016。
- 闰年判断
- 从实例中理解框架
- 骗子的逻辑
- php实现选择排序
- AFNetWorking常用方法
- UESTC 1264 人民币的构造
- 隐藏和显示
- Resource: bean/Product.hbm.xml not found
- c++11 访问者模式
- 深入了解 Flash Cache
- 写一点opengl的初步入门理解
- Arduino 和 RPi 在家居控制方面的各种实践
- 如何高效的读懂代码
- UIScrollView的代理(delegate)