标签:style class blog http tar get
题目链接:http://acm.upc.edu.cn/problem.php?id=2170
题意:给出一个字符串,比如ABACA,在这个串里,AB、BA、AC、CA各出现一次。若存在另外一个串,里面也AB、BA、AC、CA各出现一次。我们称ABACA是不唯一的。给出一个串,判断其是不是唯一。
思路:将字母看做顶点,将相邻的连有向边。那么题 目转化成这个图是不是存在两条欧拉路径。现在这个图至少有一条欧拉路径。设原串最后一个字母对应的节点为end。那么现在的图中若存在一个点u,对于这个 u至少有两个节点v1,v2,使得存在<u,v1><u,v2>,并且删掉两个中的任意一条后end都可由u到达,则说明有两个 欧拉路径。我们现在假设u只有这两个子节点v1,v2,那么原来的欧拉回路必然是走的<u,v1>或者 <u,v2>,不妨是<u,v1>,那么对于u、v1、v2、end四个点的顺序大致有两种情况:
(1)u->v1->v2->u->v2->end
(2)u->v1->u->v2->end
那么对于边<u,v2>,若将其删除后,如能够到达end,那么只能是情况(1),此时两条欧拉路径除了(1)之外另一条是
u->v2->u->v1->v2->end。另外有一种情况上面的算法不能涉及,就是ABCDA,也就是前后两个是一样
的情况,这个必然是不唯一的,因为你存在了环,如BCDAB,CDABC等。
int a[30][30],d[30]; char s[N]; int n,end,flag; int allSame() { int i; FOR0(i,n) if(s[i]!=s[0]) return 0; return 1; } int h[30],last; void DFS(int x) { h[x]=1; int i; FOR0(i,26) if(!h[i]&&a[x][i]) DFS(i); } int OK(int x) { clr(h,0); DFS(x); return h[last]; } void deal() { int cnt,i,j; FOR0(i,26) if(d[i]>1) { cnt=0; FOR0(j,26) if(a[i][j]>0) { a[i][j]--; if(OK(i)) cnt++; a[i][j]++; } if(cnt>1) { puts("not unique"); return; } } puts("unique"); } int main() { rush() { RD(s); n=strlen(s); int i,j; clr(a,0); clr(d,0); FOR0(i,n-1) { a[s[i]-‘A‘][s[i+1]-‘A‘]++; } FOR0(i,26) FOR0(j,26) if(a[i][j]) d[i]++; if(!allSame()&&s[0]==s[n-1]) { puts("not unique"); continue; } last=s[n-1]-‘A‘; deal(); } return 0; }
UPC 2170 D Equal Is Not Really Equal (欧拉路径),布布扣,bubuko.com
UPC 2170 D Equal Is Not Really Equal (欧拉路径)
标签:style class blog http tar get
原文地址:http://www.cnblogs.com/jianglangcaijin/p/3799766.html