POJ1237 The Postal Worker Rings Once

                                                                           The Postal Worker Rings Once
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 515 Accepted: 331

Description

Graph algorithms form a very important part of computer science and have a lineage that goes back at least to Euler and the famous Seven Bridges of Konigsberg problem. Many optimization problems involve determining efficient methods for reasoning about graphs.


This problem involves determining a route for a postal worker so that all mail is delivered while the postal worker walks a minimal distance, so as to rest weary legs.
Given a sequence of streets (connecting given intersections) you are to write a program that determines the minimal cost tour that traverses every street at least once. The tour must begin and end at the same intersection.


The ``real-life'' analogy concerns a postal worker who parks a truck at an intersection and then walks all streets on the postal delivery route (delivering mail) and returns to the truck to continue with the next route.


The cost of traversing a street is a function of the length of the street (there is a cost associated with delivering mail to houses and with walking even if no delivery occurs).


In this problem the number of streets that meet at a given intersection is called the degree of the intersection. There will be at most two intersections with odd degree. All other intersections will have even degree, i.e., an even number of streets meeting at that intersection.

Input

The input consists of a sequence of one or more postal routes. A route is composed of a sequence of street names (strings), one per line, and is terminated by the string ``deadend'' which is NOT part of the route. The first and last letters of each street name specify the two intersections for that street, the length of the street name indicates the cost of traversing the street. All street names will consist of lowercase alphabetic characters.


For example, the name foo indicates a street with intersections f and o of length 3, and the name computer indicates a street with intersections c and r of length 8. No street name will have the same first and last letter and there will be at most one street directly connecting any two intersections. As specified, the number of intersections with odd degree in a postal route will be at most two. In each postal route there will be a path between all intersections, i.e., the intersections are connected.

Output

For each postal route the output should consist of the cost of the minimal tour that visits all streets at least once. The minimal tour costs should be output in the order corresponding to the input postal routes.

Sample Input

one
two
three
deadend
mit
dartmouth
linkoping
tasmania
york
emory
cornell
duke
kaunas
hildesheim
concord
arkansas
williams
glasgow
deadend

Sample Output

11
114

Source

 
 
 
思路:每个字符串表示两个点以及这两个点之间的距离,字符串的都是小写字母,字符串的第一个字母和最后一个字母表示点,字符串的长度表示两点之间的距离(两点之间的距离没有方向),没有重边。同时,这些点里面,最多只有两个点的度为奇数,其余全部为偶数。求遍历所有点所经过的最少路径。在体重只有两种情况:1.所有点的度数都是偶数。2.所有点中度数为奇数的度数恰好两个(因为每条边产生2度,所以所有度的总和一定是偶数,所以不会出现一个奇度点)。在第1中情况中,这个图刚好构成欧拉图,欧拉图经过所有边一次恰好能够遍历所有点,所以结果为所有边的和。在第2种情况中,这个图构成一个欧拉通路,如果将两个奇度点之间再人为的加上一条边,则构成了欧拉图,而这条边的长度就是这两个点之间的最短距离。
 
 
  1 #include <cstdlib>
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <string>
  6 #include <cctype>
  7 #include <cmath>
  8 #include <queue>
  9 #include <vector>
 10 
 11 
 12 #define MAXINT 99999999
 13 
 14 
 15 using namespace std;
 16 
 17 
 18 int data[100][100];
 19 int vis[100];
 20 int degree[100];
 21 
 22 
 23 int lowcost[100];
 24 
 25 
 26 
 27 
 28 int main(int argc, char *argv[])
 29 {
 30     char tmpStr[1000];
 31     
 32     int i,j,k;
 33     int sum=0;
 34     
 35     
 36     while(scanf("%s",tmpStr)!=EOF)
 37     {
 38                                   if(strcmp(tmpStr,"deadend")==0)
 39                                   continue;
 40                                   
 41                                   getchar();
 42                                   
 43                                   sum=0;
 44                                   
 45                                   
 46                                   for(i=0;i<26;i++)
 47                                   for(j=0;j<26;j++)
 48                                   data[i][j]=MAXINT;
 49                                   
 50                                   for(i=0;i<26;i++)
 51                                   degree[i]=vis[i]=0;
 52                                   
 53                                   int len=strlen(tmpStr);
 54                                   
 55                                   data[tmpStr[0]-'a'][tmpStr[len-1]-'a']=len;
 56                                   data[tmpStr[len-1]-'a'][tmpStr[0]-'a']=len;
 57                                   degree[tmpStr[0]-'a']++;
 58                                   degree[tmpStr[len-1]-'a']++;
 59                                   
 60                                   sum+=len;
 61                                   
 62                                   
 63                                   
 64                                   while(scanf("%s",tmpStr)!=EOF)
 65                                   {if(strcmp(tmpStr,"deadend")==0)
 66                                     break;
 67                                     
 68                                     getchar();
 69                                     
 70                                     len=strlen(tmpStr);
 71                                     
 72                                     
 73                                   data[tmpStr[0]-'a'][tmpStr[len-1]-'a']=len;
 74                                   data[tmpStr[len-1]-'a'][tmpStr[0]-'a']=len;
 75                                   degree[tmpStr[0]-'a']++;
 76                                   degree[tmpStr[len-1]-'a']++;
 77                                   
 78                                   sum+=len;
 79                                   
 80                                   
 81                                   }
 82                                   
 83                                   
 84                                   
 85                                   for(i=0;i<26;i++)
 86                                   if(degree[i]%2==1)
 87                                   break;
 88                                   
 89                                   
 90                                   
 91                                   if(i>=26)
 92                                   {
 93                                            printf("%d\n",sum);
 94                                            continue;
 95                                   }
 96                                   
 97                                   int beginv=i;
 98                                   
 99                                   for(i++;i<26;i++)
100                                   if(degree[i]%2==1)
101                                   break;
102                                   
103                                   
104                                   
105                                   
106                                   
107                                   int endv=i;
108                                   
109                                  
110                                   
111                                   
112                                   
113                                   for(j=0;j<26;j++)
114                                   {vis[j]=0;lowcost[j]=data[beginv][j];}
115                                   
116                                   int mincost=MAXINT;
117                                   
118                                   
119                                   vis[beginv]=1;
120                                   
121                                   for(i=1;i<26;i++)
122                                   {
123                                                    mincost=MAXINT;
124                                                    k=-1;
125                                                    
126                                                    for(j=0;j<26;j++)
127                                                    {if((vis[j]==0)&&(mincost>lowcost[j]))
128                                                     {k=j;mincost=lowcost[j];}
129                                                    }
130                                                    
131                                                    vis[k]=1;
132                                                   
133                                                    
134                                                    
135                                                    if(k==endv)
136                                                    break;
137                                                    
138                                                    for(j=0;j<26;j++)
139                                                    {
140                                                                     if((vis[j]==0)&&(lowcost[k]+data[k][j]<lowcost[j]))
141                                                                     lowcost[j]=lowcost[k]+data[k][j];
142                                                    }
143                                                    
144                                   }
145                                   
146                                  
147                                   sum+=lowcost[endv];
148                                   printf("%d\n",sum);
149     }
150                                                    
151                                   
152                                   
153                                   
154                                   
155                                   
156                                   
157                                   
158                                   
159                                   
160                                   
161                                   
162                                   
163                                   
164                                   
165                                   
166                                   
167                                   
168                                   
169                                     
170                                   
171                                   
172                                  
173     
174     
175             
176     
177     //system("PAUSE");
178     return EXIT_SUCCESS;
179 }

 

转载于:https://www.cnblogs.com/zjushuiping/archive/2012/08/04/2623044.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值