欧拉路
欧拉路:
如果给定无孤立结点图G,若存在一条路,经过图中每边一次且仅一次,这条路称为欧拉路;
如果给定无孤立结点图G,若存在一条回路,经过图中每边一次且仅一次,那么该回路称为欧拉回路。
存在欧拉回路的图,称为欧拉图。
一、 对于无向图G,具有一条欧拉路,当且仅当G是连通的,且有零个或两个奇数度结点。
且有零个奇数度结点,存在欧拉回路;有两个奇数度结点,存在欧拉路。
判断无向图G是否连通,可以从任意结点出发,进行深度优先遍历,如果可以遍历到所有点,也可以用并查集,判断根节点的个数,
说明,图G连通,否则,图G不连通。
http://acm.nyist.net/JudgeOnline/problem.php?pid=42
#include<stdio.h> #include<string.h> int pre[1001]; int dds[1001]; void init(int n) { int i; for(i=1;i<=n;i++) pre[i]=i; } int find(int x) { if(x!=pre[x]) pre[x]=find(pre[x]); return pre[x]; } void uunion(int x,int y) { x=find(x); y=find(y); if(x!=y) pre[y]=x; } int main() { int i,j,k,cc,n,m; int start, end; scanf("%d",&cc); while(cc--) { memset(dds,0,sizeof(dds)); scanf("%d%d",&n,&m); init(n); for(i=1;i<=m;i++) { scanf("%d%d",&start,&end); uunion(start,end); dds[start]=!dds[start];//只记录奇偶性,1为奇度,0为偶度 dds[end]=!dds[end]; } int sum_root=0,sum_ji=0;//根结点的个数,记录奇度顶点个数 for(i=1;i<=n;i++) { if(pre[i]==i) sum_root++; if(dds[i]) sum_ji++; } if(sum_root>1) { printf("No\n"); continue;} if(sum_ji==0||sum_ji==2) printf("Yes\n"); else printf("No\n"); } return 0; }
http://acm.nyist.net/JudgeOnline/problem.php?pid=230 彩色棒
#include<stdio.h> #include<string.h> #include<stdlib.h> #define maxn 500002 typedef struct node { int order; //编号。 struct node *next[26]; }node; int pre[maxn]; int vs[maxn]; int t; int search(char *s,node *T) { int len,i,j,id,flag=0; node *p,*q; len=strlen(s); p=T; for(i=0;i<len;++i) { id=s[i]-'a'; if(p->next[id]==NULL) { flag=1; q=(node *)malloc(sizeof(node)); for(j=0;j<26;++j) q->next[j]=NULL; p->next[id]=q; } p=p->next[id]; } if(flag) //颜色不存在。 { p->order=t++; vs[p->order]=!vs[p->order]; return p->order; } else { vs[p->order]=!vs[p->order]; return p->order; } } int find(int x) { if(pre[x]==-1) return x; return pre[x]=find(pre[x]); } void Union(int x,int y) { x=find(x); y=find(y); if(x!=y) pre[y]=x; } int main() { //freopen("Input.txt","r",stdin); int i,num1,num2,ncase,n; char s1[20],s2[20]; node *T; scanf("%d",&ncase); while(ncase--) { t=1; memset(vs,0,sizeof(vs)); memset(pre,-1,sizeof(pre)); T=(node *)malloc(sizeof(node)); T->order=0; for(i=0;i<26;++i) T->next[i]=NULL; scanf("%d",&n); if(n==0) { printf("Possible\n"); continue ;} for(i=1;i<=n;i++) { scanf("%s%s",s1,s2); num1=search(s1,T); num2=search(s2,T); Union(num1,num2); } int ans=0,sum=0; for(i=1;i<t;i++) { if(pre[i]==-1) ans++; if(vs[i]) sum++; } if(ans>1) printf("Impossible\n"); else { if(sum==2||sum==0) printf("Possible\n"); else printf("Impossible\n"); } } return 0; }
二 、对于有向图G,具有一条单向欧拉路,当且仅当G是连通的,且每个结点入度等于出度,或者,
除两个结点外,每个结点的入度等于出度,而这两个结点满足,一个结点的入度比出度大1,
另一个结点的入度比出度小1。
判断有向图G是否连通,可以某一结点出发,进行深度优先遍历,如果存在一点作为初始结点
可以遍历到所有点,说明,图G连通,否则,图G不连通。