/*混合图的欧拉回路 
混合图欧拉回路
原来混合图欧拉回路用的是网络流。
把该图的无向边随便定向,计算每个点的入度和出度。如果有某个点出入度之差为奇数,
那么肯定不存在欧拉回路。因为欧拉回路要求每点入度 = 出度,也就是总度数为偶数,存在奇数度点必不能有欧拉回路。
好了,现在每个点入度和出度之差均为偶数。那么将这个偶数除以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>
#include<iostream>
  2 #include<cstdio>
#include<cstdio>
  3 #include<cstring>
#include<cstring>
  4 using namespace std;
using namespace std;
  5 #define MAXV 30
#define MAXV 30
  6 #define MAXE 100000
#define MAXE 100000 
  7 #define INF 0x1f1f1f1f
#define INF 0x1f1f1f1f
  8 int flag[MAXV],used[MAXV],head[MAXV],q[MAXV],ind[MAXV],outd[MAXV],level[MAXV];
int flag[MAXV],used[MAXV],head[MAXV],q[MAXV],ind[MAXV],outd[MAXV],level[MAXV];
  9 int src,dest,pe;
int src,dest,pe;
 10 int mp[MAXV][MAXV];
int mp[MAXV][MAXV];
 11 void dfs(int x)
void dfs(int x)
 12

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

 {
{
 20 int v,next,dup;
       int v,next,dup;
 21 int cap,f;
       int cap,f;
 22
 node()
       node() {}
{}
 23
 node(int _v,int _next,int _dup,int _cap,int _f):v(_v),next(_next),dup(_dup),cap(_cap),f(_f)
       node(int _v,int _next,int _dup,int _cap,int _f):v(_v),next(_next),dup(_dup),cap(_cap),f(_f) {}
{}
 24 }Elist[MAXE];
}Elist[MAXE];
 25
 26 inline void add_edge(int u,int v,int cap,int f=0)
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);
       Elist[pe]=node(v,head[u],pe+1,cap,f);
 29 head[u]=pe++;
       head[u]=pe++;
 30 Elist[pe]=node(u,head[v],pe-1,0,-f);
       Elist[pe]=node(u,head[v],pe-1,0,-f);
 31 head[v]=pe++;
       head[v]=pe++;
 32 }
}
 33 bool dinic_bfs()
bool dinic_bfs()
 34

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

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