HDU 3472 HS BDC (混合图的欧拉路径判断)


HS BDC

Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 748Accepted Submission(s): 290


Problem Description
IELTS is around the corner! love8909 has registered for the exam, but he still hasn’t got prepared. Now he decides to take actions. But when he takes out the New Oriental IELTS Vocabulary, he finds there are so many words. But love8909 doesn’t get scared, because he has got a special skill. If he can make a list with some meaningful words, he will quickly remember these words and will not forget them. If the last letter of some word Wa is the same as the first letter of some word Wb, then you can connect these two words and make a list of two words. If you can connect a word to a list, you will make a longer list.

While love8909 is making the list, he finds that some words are still meaningful words if you reverse them. For example, if you reverse the word “pat”, you will get another meaningful word “tap”.

After scanning the vocabulary, love8909 has found there are N words, some of them are meaningful if reversed, while others are not. Now he wonders whether he can remember all these words using his special skill.

The N-word list must contain every word once and only once.

Input
An integer T (T <= 50) comes on the first line, indicating the number of test cases.

On the first line of each test cases is an integer N (N <= 1000), telling you that there are N words that love8909 wants to remember. Then comes N lines. Each of the following N lines has this format: word type. Word will be a string with only ‘a’~’z’, and type will be 0(not meaningful when reversed) or 1(meaningful when reversed). The length of each word is guaranteed to be less than 20.

Output
The format of the output is like “Case t: s”, t is the number of the test cases, starting from 1, and s is a string.
For each test case, if love8909 can remember all the words, s will be “Well done!”, otherwise it’s “Poor boy!”

Sample Input
3 6 aloha 0 arachnid 0 dog 0 gopher 0 tar 1 tiger 0 3 thee 1 earn 0 nothing 0 2 pat 1 acm 0

Sample Output
Case 1: Well done! Case 2: Well done! Case 3: Poor boy! Hint In the first case, the word “tar” is still meaningful when reversed, and love8909 can make a list as “aloha-arachnid-dog-gopher-rat-tiger”. In the second case, the word “thee” is still meaningful when reversed, and love8909 can make a list as “thee-earn-nothing”. In the third case, no lists can be created.

Author
allenlowesy

Source
2010 ACM-ICPC Multi-University Training Contest(4)——Host by UESTC

几乎就是模板题了。

先要判断连通。

然后转化成网络流判断欧拉回路。

  1 /* ***********************************************
  2 Author        :kuangbin
  3 Created Time  :2014-2-3 15:00:40
  4 File Name     :E:\2014ACM\专题学习\图论\欧拉路\混合图\HDU3472.cpp
  5 ************************************************ */
  6 
  7 #include <stdio.h>
  8 #include <string.h>
  9 #include <iostream>
 10 #include <algorithm>
 11 #include <vector>
 12 #include <queue>
 13 #include <set>
 14 #include <map>
 15 #include <string>
 16 #include <math.h>
 17 #include <stdlib.h>
 18 #include <time.h>
 19 using namespace std;
 20 
 21 const int MAXN = 30;
 22 //最大流部分
 23 const int MAXM = 10000;
 24 const int INF = 0x3f3f3f3f;
 25 struct Edge
 26 {
 27     int to,next,cap,flow;
 28 }edge[MAXM];
 29 int tol;
 30 int head[MAXN];
 31 int gap[MAXN], dep[MAXN], pre[MAXN], cur[MAXN];
 32 void init()
 33 {
 34     tol = 0;
 35     memset(head,-1,sizeof(head));
 36 }
 37 void addedge(int u,int v,int w,int rw = 0)
 38 {
 39     edge[tol].to = v;
 40     edge[tol].cap = w;
 41     edge[tol].next = head[u];
 42     edge[tol].flow = 0;
 43     head[u] = tol++;
 44     edge[tol].to = u;
 45     edge[tol].cap = rw;
 46     edge[tol].next = head[v];
 47     edge[tol].flow = 0;
 48     head[v] = tol++;
 49 }
 50 int sap(int start,int end,int N)
 51 {
 52     memset(gap,0,sizeof(gap));
 53     memset(dep,0,sizeof(dep));
 54     memcpy(cur,head,sizeof(head));
 55     int u = start;
 56     pre[u] = -1;
 57     gap[0] = N;
 58     int ans = 0;
 59     while(dep[start] < N)
 60     {
 61         if(u == end)
 62         {
 63             int Min = INF;
 64             for(int i = pre[u];i != -1;i = pre[edge[i^1].to])
 65                 if(Min > edge[i].cap - edge[i].flow)
 66                     Min = edge[i].cap - edge[i].flow;
 67             for(int i = pre[u]; i != -1;i = pre[edge[i^1].to])
 68             {
 69                 edge[i].flow += Min;
 70                 edge[i^1].flow -= Min;
 71             }
 72             u = start;
 73             ans += Min;
 74             continue;
 75         }
 76         bool flag = false;
 77         int v;
 78         for(int i = cur[u]; i != -1;i = edge[i].next)
 79         {
 80             v = edge[i].to;
 81             if(edge[i].cap - edge[i].flow && dep[v] + 1 == dep[u])
 82             {
 83                 flag = true;
 84                 cur[u] = pre[v] = i;
 85                 break;
 86             }
 87         }
 88         if(flag)
 89         {
 90             u = v;
 91             continue;
 92         }
 93         
 94         int Min = N;
 95         for(int i = head[u];  i != -1;i = edge[i].next)
 96             if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)
 97             {
 98                 Min = dep[edge[i].to];
 99                 cur[u] = i;
100             }
101         gap[dep[u]] --;
102         if(!gap[dep[u]])return ans;
103         dep[u] = Min+1;
104         gap[dep[u]]++;
105         if(u != start) u = edge[pre[u]^1].to;
106     }
107     return ans;
108 }
109 
110 int in[30],out[30];
111 int F[30];
112 int find(int x)
113 {
114     if(F[x] == -1)return x;
115     else return F[x] = find(F[x]);
116 }
117 void bing(int u,int v)
118 {
119     int t1 = find(u), t2 = find(v);
120     if(t1 != t2)F[t1] = t2;
121 }
122 char str[100];
123 int main()
124 {
125     //freopen("in.txt","r",stdin);
126     //freopen("out.txt","w",stdout);
127     int T,n;
128     scanf("%d",&T);
129     int iCase = 0;
130     while(T--)
131     {
132         iCase++;
133         scanf("%d",&n);
134         memset(F,-1,sizeof(F));
135         memset(in,0,sizeof(in));
136         memset(out,0,sizeof(out));
137         init();
138         int k;
139         int s = -1;
140         while(n--)
141         {
142             scanf("%s%d",str,&k);
143             int len = strlen(str);
144             int u = str[0] - 'a';
145             int v = str[len-1] - 'a';
146             out[u]++;
147             in[v]++;
148             s = u;
149             if(k == 1)
150                 addedge(u,v,1);
151             bing(u,v);
152         }
153         bool flag = true;
154         int cnt = 0;
155         int s1 = -1, s2 = -1;
156         for(int i = 0;i < 26;i++)
157             if(in[i] || out[i])
158             {
159                 if(find(i) != find(s))
160                 {
161                     flag = false;
162                     break;
163                 }
164                 if((in[i] + out[i])&1)
165                 {
166                     cnt++;
167                     if(s1 == -1)s1 = i;
168                     else s2 = i;
169                 }
170             }
171         if(cnt != 0 && cnt != 2)flag = false;
172         if(!flag)
173         {
174             printf("Case %d: Poor boy!\n",iCase);
175             continue;
176         }
177         if(cnt == 2)
178         {
179             out[s1]++;
180             in[s2]++;
181             addedge(s1,s2,1);
182         }
183         for(int i = 0;i < 26;i++)
184         {
185             if(out[i] - in[i] > 0)
186                 addedge(26,i,(out[i] - in[i])/2);
187             else if(in[i] - out[i] > 0)
188                 addedge(i,27,(in[i] - out[i])/2);
189         }
190         sap(26,27,28);
191         for(int i = head[26];i != -1;i = edge[i].next)
192             if(edge[i].cap > 0 && edge[i].cap > edge[i].flow)
193             {
194                 flag = false;
195                 break;
196             }
197         if(flag)printf("Case %d: Well done!\n",iCase);
198         else printf("Case %d: Poor boy!\n",iCase);
199     }
200     return 0;
201 }

优质内容筛选与推荐>>
1、T-Sql 语法小结
2、每日一句 之 put a bug in one's ear.
3、巴拿赫空间的基本性质
4、L300 3月英语课下
5、ios开发——常用经典算法OC篇&冒泡/快速


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn