欧拉路:
如果给定无孤立结点图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不连通。