/*混合图的欧拉回路
混合图欧拉回路
原来混合图欧拉回路用的是网络流。
把该图的无向边随便定向,计算每个点的入度和出度。如果有某个点出入度之差为奇数,
那么肯定不存在欧拉回路。因为欧拉回路要求每点入度 = 出度,也就是总度数为偶数,存在奇数度点必不能有欧拉回路。
好了,现在每个点入度和出度之差均为偶数。那么将这个偶数除以2,得x。
也就是说,对于每一个点,只要将x条边改变方向(入>出就是变入,出>入就是变出),
就能保证出 = 入。如果每个点都是出 = 入,那么很明显,该图就存在欧拉回路。
现在的问题就变成了:我该改变哪些边,可以让每个点出 = 入?构造网络流模型。首先,有向边是不能改变方向的,要之无用,删。
一开始不是把无向边定向了吗?定的是什么向,就把网络构建成什么样,边长容量上限1。另新建s和t。对于入 > 出的点u,连接边(u, t)、容量为x,
对于出 > 入的点v,连接边(s, v),容量为x(注意对不同的点x不同)。之后,察看是否有满流的分配。有就是能有欧拉回路,没有就是没有。欧拉回路是哪个?
察看流值分配,将所有流量非0(上限是1,流值不是0就是1)的边反向,就能得到每点入度 = 出度的欧拉图。
由于是满流,所以每个入 > 出的点,都有x条边进来,将这些进来的边反向,OK,入 = 出了。对于出 > 入的点亦然。
那么,没和s、t连接的点怎么办?和s连接的条件是出 > 入,和t连接的条件是入 > 出,那么这个既没和s也没和t连接的点,自然早在开始就已经满足入 = 出了。
那么在网络流过程中,这些点属于“中间点”。我们知道中间点流量不允许有累积的,这样,进去多少就出来多少,反向之后,自然仍保持平衡。
所以,就这样,混合图欧拉回路问题,解了.
上文是pku的discuss中的,下面自己总结一下。
混合图的欧拉回路, 既然是欧拉回路首先图必须是连通的:将所有边看成无向边做一遍dfs判断连通性。
要构成欧拉图最后所以得点入度都等于出度,即需要每个点入度和出度之差为偶数,若有两个点为奇数可能有欧拉路,
这时只需要在这两个点之间加一条边,即可转化为欧拉回路问题。
判断完毕后,如果所有点入度和出度差为偶数,构建网络流图,原来图中的有向边,可以删去。
原来的无向边可以任意指定一个方向,之后对所有入度大于出度的点引一条边到汇点,边权为入度与出度差的一半。
对于出度大于入度的点从源点引一条边过来,边权为出度和入度差的一半,最后求最大流,若是漫流,则证明有欧拉回路。
1
#include<iostream>
2
#include<cstdio>
3
#include<cstring>
4
using namespace std;
5
#define MAXV 30
6
#define MAXE 100000
7
#define INF 0x1f1f1f1f
8
int flag[MAXV],used[MAXV],head[MAXV],q[MAXV],ind[MAXV],outd[MAXV],level[MAXV];
9
int src,dest,pe;
10
int mp[MAXV][MAXV];
11
void dfs(int x)
12

{
13
flag[x]=1;
14
for(int i=0;i<26;i++)
15
if(!flag[i]&&mp[x][i])
16
dfs(i);
17
}
18
struct node
19

{
20
int v,next,dup;
21
int cap,f;
22
node()
{}
23
node(int _v,int _next,int _dup,int _cap,int _f):v(_v),next(_next),dup(_dup),cap(_cap),f(_f)
{}
24
}Elist[MAXE];
25
26
inline void add_edge(int u,int v,int cap,int f=0)
27

{
28
Elist[pe]=node(v,head[u],pe+1,cap,f);
29
head[u]=pe++;
30
Elist[pe]=node(u,head[v],pe-1,0,-f);
31
head[v]=pe++;
32
}
33
bool dinic_bfs()
34

{
35
int qs(0),qe(1),p;
36
memset(level,-1,sizeof(level));
37
level[src]=0;
38
q[0]=src;
39
while(qs<qe)
40
{
41
for(p=head[q[qs]];p!=-1;p=Elist[p].next)
42
{
43
if(level[Elist[p].v]==-1&&Elist[p].cap>Elist[p].f)
44
{
45
level[Elist[p].v]=level[q[qs]]+1;
46
q[qe++]=Elist[p].v;
47
}
48
}
49
qs++;
50
}
51
return level[dest]!=-1;
52
}
53
54
int Dinic()
{
55
int sh, cur, u, i, *stack = q, p;
56
int ans(0), m;
57
while(dinic_bfs())
{
58
// cout<<"after bfs "<<endl;
59
sh = 1;
60
stack[0] = src;
61
while(sh != -1)
{
62
cur = stack[sh-1]; //一个点的ID接着一个边的ID
63
if(cur == dest)
{
64
m = (1<<30);
65
for(i = 1; i < sh; ++i, ++i)
66
if(m > Elist[stack[i]].cap - Elist[stack[i]].f)
{
67
m = Elist[stack[i]].cap - Elist[stack[i]].f;
68
u = i;
69
}
70
for(i = 1; i < sh; ++i, ++i)
{
71
Elist[stack[i]].f += m;
72
Elist[Elist[stack[i]].dup].f -= m;
73
}
74
ans += m;
75
sh = u;
76
}
77
else
{
78
for(p = head[cur]; p != -1; p = Elist[p].next)
79
if(level[Elist[p].v] == level[cur]+1 &&Elist[p].cap > Elist[p].f)
{
80
stack[sh++] = p;
81
stack[sh++] = Elist[p].v;
82
break;
83
}
84
if(p == -1)
{
85
level[cur] = -1;
86
--sh, --sh;
87
}
88
}
89
}
90
}
91
return ans;
92
}
93
94
int main()
95

{
96
int t,test,n,i,f,u,v;
97
scanf("%d",&test);
98
for(t=1;t<=test;t++)
99
{
100
scanf("%d",&n);
101
char str[100];
102
memset(head,-1,sizeof(head));
103
pe=0;
104
memset(mp,0,sizeof(mp));
105
memset(flag,0,sizeof(flag));
106
memset(used,0,sizeof(used));
107
memset(ind,0,sizeof(ind));
108
memset(outd,0,sizeof(outd));
109
src=26;dest=27;
110
for(i=0;i<n;i++)
111
{
112
scanf("%s",str);
113
scanf("%d",&f);
114
u=str[0]-'a';
115
outd[u]++;
116
v=str[strlen(str)-1]-'a';
117
ind[v]++;
118
mp[u][v]=mp[v][u]=1;
119
used[u]=used[v]=1;
120
if(f)
121
add_edge(u,v,1);
122
}
123
printf("Case %d: ",t);
124
for(i=0;i<26;i++)
125
if(used[i])
126
{
127
dfs(i);
128
break;
129
}
130
for(i=0;i<26;i++)
131
if(used[i]&&!flag[i])
132
{
133
printf("Poor boy!\n");
134
break;
135
}
136
if(i!=26) continue;
137
int total,sum;
138
total=sum=0;
139
for(i=0;i<26;i++)
140
if(used[i])
141
{
142
if((ind[i]-outd[i])%2!=0)
143
{
144
total++;
145
if(total==1)
146
u=i;
147
else if(total==2)
148
v=i;
149
}
150
}
151
if(total==1||total>2)
152
{
153
printf("Poor boy!\n");
154
continue;
155
}
156
if(total==2)
157
{
158
ind[u]++;
159
outd[v]++;
160
add_edge(v,u,1);
161
}
162
for(i=0;i<26;i++)
163
{
164
if(outd[i]>ind[i])
165
{
166
add_edge(src,i,(outd[i]-ind[i])/2);
167
sum+=(outd[i]-ind[i])/2;
168
}
169
else if(ind[i]>outd[i])
170
add_edge(i,dest,(ind[i]-outd[i])/2);
171
}
172
int tmp=Dinic();
173
if(tmp==sum)
174
printf("Well done!\n");
175
else
176
printf("Poor boy!\n");
177
178
179
}
180
return 0;
181
}
182
183