对于欧拉回路,先判断出度入度的差是否为偶数,然后最大流一次。

此题是判断有无欧拉通路,前提要判断图是否连通,然后欧拉通路的条件:要么出入度差没有奇数,或者只有2个点。

所以先统计差为奇数的个数,如果不为0或2,不可能。然后如果为2,表示可能使欧拉路,所以此时可以将这两个点相连,类似添加一条无向边。然后就是判断是否为欧拉回路了。

#include<stdio.h>
#include<string.h>
#include<queue>
#define maxn 50
#define INF 9999999
using namespace std;
struct node
{
int to;
int v;
int flag;
int next;
}edge[*];
char s[][];
int vis[maxn],pre[maxn],index,in[maxn],out[maxn],n,sum,t,ff;
int pa[maxn];
int find(int x)
{
if(pa[x]!=x)pa[x]=find(pa[x]);
return pa[x];
}
void add(int x,int y,int z)
{
edge[index].to=y;
edge[index].v=z;
edge[index].flag=index+;
edge[index].next=pre[x];
pre[x]=index++;
edge[index].to=x;
edge[index].v=;
edge[index].flag=index-;
edge[index].next=pre[y];
pre[y]=index++;
}
int dfs(int u,int low)
{
int i;
if(u==t)
return low;
for(i=pre[u];i!=-;i=edge[i].next)
{
if(vis[edge[i].to]==vis[u]+&&edge[i].v)
{
int a=dfs(edge[i].to,min(low,edge[i].v));
if(!a)continue;
edge[i].v-=a;
edge[edge[i].flag].v+=a;
return a;
}
}
return ;
}
int BFS()
{
int i;
queue<int>q;
memset(vis,-,sizeof(vis));
vis[]=;
q.push();
while(!q.empty())
{
int t=q.front();
q.pop();
for(i=pre[t];i!=-;i=edge[i].next)
{
if(vis[edge[i].to]<&&edge[i].v)
{
vis[edge[i].to]=vis[t]+;
q.push(edge[i].to);
}
}
}
if(vis[t]>)
return ;
return ;
}
void Dinic()
{
int ans=;
while(BFS())
{
while()
{
int a=dfs(,INF);
if(!a)break;
ans+=a;
}
}
if(ans==sum)
printf("Case %d: Well done!\n",++ff);
else
printf("Case %d: Poor boy!\n",++ff);
}
void slove(int fs)
{
int i,st,se;//欧拉路奇数点的开始结束点
st=se=-;
int count=,flag=;
for(i=;i<='z'-'a'+;i++)
{
if(in[i]||out[i])
{
if(find(i)!=find(fs))
{
flag=;
break;
}
else if((out[i]-in[i])%!=)
{
count++;
if(st==-)st=i;
else se=i;
}
}
}
if(count!=&&count!=) flag=; if(flag)
printf("Case %d: Poor boy!\n",++ff);
else
{
if(count==)
{
add(st,se,);
out[st]++;
in[se]++;
}
for(i=;i<='z'-'a'+;i++)
{
if(out[i]>in[i])
{
add(,i,(out[i]-in[i])/);
sum+=((out[i]-in[i])/);
}
else if(in[i]>out[i])
{
add(i,t,(in[i]-out[i])/);
}
}
Dinic();
}
}
int init()
{
int i,fs;
t='z'-'a'+;
sum=;
index=;
for(i=;i<=;i++)pa[i]=i;
memset(pre,-,sizeof(pre));
memset(in,,sizeof(in));
memset(out,,sizeof(out));
scanf("%d",&n);
for(i=;i<=n;i++)
{
int z;
scanf("%s %d",s[i],&z);
int l=strlen(s[i]);
int x=s[i][]-'a'+;
int y=s[i][l-]-'a'+;
in[y]++,out[x]++,fs=x;
int fx=find(x),fy=find(y);
if(fx!=fy)pa[fx]=fy;
if(z)
{
add(x,y,);
}
}
return fs;
}
int main()
{
ff=;
int t,father;
scanf("%d",&t);
while(t--)
{
father=init();
slove(father);
}
}

hdu3472 混合图判断欧拉通路的更多相关文章

  1. POJ 2337 Catenyms(有向图的欧拉通路)

    题意:给n个字符串(3<=n<=1000),当字符串str[i]的尾字符与str[j]的首字符一样时,可用dot连接.判断用所有字符串一次且仅一次,连接成一串.若可以,输出答案的最小字典序 ...

  2. 欧拉通路-Play on Words 分类: POJ 图论 2015-08-06 19:13 4人阅读 评论(0) 收藏

    Play on Words Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 10620 Accepted: 3602 Descri ...

  3. POJ 2513 Colored Sticks (离散化+并查集+欧拉通路)

    下面两个写得很清楚了,就不在赘述. http://blog.sina.com.cn/s/blog_5cd4cccf0100apd1.htmlhttp://www.cnblogs.com/lyy2890 ...

  4. POJ 1386 有向图欧拉通路

    题意:给你一些字符串,这些字符串可以首位相接(末位置如果和另一个字符串的首位置相同的话就可以相连) .然后问你是否可以全部连起来. 思路:就是取出每个字符串的首尾位置,然后求出出度和入度,根据有向欧拉 ...

  5. CodeForces - 508D Tanya and Password(欧拉通路)

    Description While dad was at work, a little girl Tanya decided to play with dad characters. She has ...

  6. Uva10129 - Play on Words 欧拉通路 DFS

    题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=105& ...

  7. 欧拉图 欧拉回路 欧拉通路 Euler

    欧拉图 本文链接:http://www.cnblogs.com/Ash-ly/p/5397702.html 定义: 欧拉回路:图G的一个回路,如果恰通过图G的每一条边,则该回路称为欧拉回路,具有欧拉回 ...

  8. 欧拉图 欧拉回路 欧拉通路 Euler的认识 (转)

    转:https://www.cnblogs.com/Ash-ly/p/5397702.html 定义: 欧拉回路:图G的一个回路,如果恰通过图G的每一条边,则该回路称为欧拉回路,具有欧拉回路的图称为欧 ...

  9. nyoj 42 一笔画 欧拉通路

    http://acm.nyist.net/JudgeOnline/problem.php?pid=42 一笔画问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 zyc ...

随机推荐

  1. Leetcode429.N-ary Tree Level Order TraversalN叉树的层序遍历

    给定一个 N 叉树,返回其节点值的层序遍历. (即从左到右,逐层遍历). 例如,给定一个 3叉树 : 返回其层序遍历: [ [1], [3,2,4], [5,6] ] 说明: 树的深度不会超过 100 ...

  2. 如约而至(walk)

    LCA大佬的做法: 考虑暴力的高斯消元,我们优化它. $\sum\limits_{j} gcd(i,j)^{c-d} i^d j^d x_j=b_i$ $\sum\limits_{j} gcd(i,j ...

  3. ubuntu中vi下删除键和上下左右键输入字符异常(ABCD)

    刚安装的Ubuntu系统,使用vi编辑文本的时候, 出现以下现象: 点删除键输入了 D 回车无效 上下左右为字母 光标乱跳 原因: 自带的vi功能问题 解决: 卸载原有vi,重新安装完整版本vim 执 ...

  4. 使用jquery封装一个可以复用的提示框

    首先在html中 <div class="backcap"> <div class="diolag"> <div class=&q ...

  5. warning: deprecated conversion from string constant to 'char*

    warning: deprecated conversion from string constant to 'char* #include<iostream> using namespa ...

  6. ztree树节点重叠问题

    使用zTree时,由于同时使用了bootstrap插件,导致样式起了冲突,生成的树都挤在一起了, 最后的解决办法是设置zTreeStyle.css文件的.ztree li ul{}属性,在里面加入he ...

  7. python自动化---各类发送邮件方法及其可能的错误

    一.发送文本邮件 可能的问题1.:需要注意,目前QQ邮箱来讲,不能收到完整的邮件,即有些内容不能显示,最好全部使用网易邮箱: 可能的问题2.:在以往的文本邮件发送中,只写了 msg = MIMETex ...

  8. round 469

    第一次打codeforces,还是太菜了 代码全部来自大神void_f C #include <cstdio> #include <vector> #include <c ...

  9. NOIP模拟 6.28

    NOIP模拟赛6.28 Problem 1 高级打字机(type.cpp/c/pas) [题目描述] 早苗入手了最新的高级打字机.最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧. 请为这 ...

  10. bzoj2212/3702 [Poi2011]Tree Rotations 线段树合并

    Description Byteasar the gardener is growing a rare tree called Rotatus Informatikus. It has some in ...