標籤:rac const 無向圖 聯通 沒有 space set _id find
http://poj.org/problem?
id=2513
最初看到 第一感覺---map 一看250000的資料量 果斷放棄
然後記得曾經看過。trie取代map。尤其當資料量特別大的時候
學到了:
1、Trie取代map的思想,能夠在單詞結尾的tree[i][tk] 這個i作為字串相應的int值 。當然這個int值也能夠用於建立並查集
2、接上。通過並查集推斷。全部的點在同一個集合圖就是聯通的,否則不聯通,注意tree[i][tk]>0 表示是單詞結尾。
x=Find(x);//這句沒有的時候調試了幾下。。。 int flag=1; for(int i=1;i<top;i++) { if(tree[i][tk] && x!=Find(i)) { flag=0; break; } if(tree[i][tk]%2)cnt++; }
注意,並查集並不保證全部在同一個集合的點的father同樣,所以還是要通過Find(x)==Find(y)推斷是不是在同一個集合,而不能father相等推斷。
。
3、無向圖歐拉通路存在的判定:
a、聯通,並查集去做
b、度數為奇數的個數為0或2---------------0 無向圖存在歐拉迴路,2 無向圖存在歐拉通路 是半歐拉圖
#include<cstdio>#include<cstring>#include <string>#include <map>#include <iostream>#include <cmath>using namespace std;#define INF 10000const int tk=26,tb='a';const int N = 5000000+1000;//2500000+1000;//int d[N];int tree[N][tk+1],top,n;int father[N],pos[N],scnt;char pat1[15],pat2[15];void init(){ top=1; scnt=n=0; memset(tree[0],0,sizeof(tree[0])); //makeset for(int i=0;i<N;i++) father[i]=i;}int Insert(char *s, int Rank=0){ int rt,nxt; for(rt=0; *s; rt=nxt,++s) { nxt=tree[rt][*s-tb]; if(!nxt) { nxt=tree[rt][*s-tb]=top; memset(tree[top],0,sizeof(tree[top])); top++; } } tree[rt][tk]++; return rt;}int Find(int x){ if(x!=father[x])father[x]=Find(father[x]); return father[x];}void Union(int x, int y){ x=Find(x),y=Find(y); if(x==y)return; father[y]=x;}int main(){ //freopen("poj2513.txt","r",stdin); init(); int cnt=0,x,y; while(scanf("%s%s",pat1,pat2)!=EOF) { x=Insert(pat1); y=Insert(pat2); Union(x,y); } x=Find(x);//這句沒有的時候調試了幾下。。。 int flag=1; for(int i=1;i<top;i++) { if(tree[i][tk] && x!=Find(i)) { flag=0; break; } if(tree[i][tk]%2)cnt++; } if(!( cnt==2 || cnt == 0) )flag=0; if(flag)printf("Possible\n"); else printf("Impossible\n"); return 0;}
poj 2513 歐拉迴路+並查集推斷是否聯通+Trie樹