poj 1237(歐拉回路+floyd)

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

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

題目大意:給定一張無向圖和邊的權值,其中度爲奇數的頂點數目不超過2個。並且一定存在一條迴路。問主人公郵遞員叔叔要經過每條邊(也就是經過次數至少爲1)的前提下,通過迴路回到原初始點的花費的最小值。

輸入輸出的處理:

假設輸入的字符串爲string str=”computer”.

則改變一個點爲’c’-‘a’=2,

另一個點’r’-‘a’,  邊權之爲字符串的長度=8;

 

 

解題思路:

本題的種種細節都在暗示我們要想到歐拉回路,譬如,度爲奇數的頂點數目不超過2,

存在一條迴路回到起始點,每條邊都要至少訪問一次(試想一下,每條邊都要訪問,如果能只訪問一次,爲什麼要訪問第二次了。)等等。

 

下面是具體思路,

由於每條邊都要訪問,故如果只要訪問一次那就最好不過了。

根據歐拉回路的定義:存在一條迴路使從初始點出發並且每條邊都只訪問一次返回原出發點點。

歐拉通路的定義若從起點出發只能訪問沒一條邊,卻不能回到原起始點,這樣的路叫作歐拉通路。

 

無向圖歐拉回路的充分必要條件:在保證圖的連通性的情況下(除去那些只有一個頂點,沒有邊的其他所有頂點的連通性),所有的頂點的度爲偶數。

無向圖歐拉通路的充分必要條件:在保證圖的連通性的情況下(除去那些只有一個頂點,沒有邊的其他所有頂點的連通性),度爲奇數的頂點只有2個,並且度小的爲起點,度大的爲終點。

 

迴歸到題目中的條件:

題目說了度爲奇數的頂點數不超過2,而且一定存在迴路。令odd表示度爲奇數的頂點數

那麼odd只能等於20,不可能出現odd1的情況。

證明如下:根據握手定則有,2|E|=d(v)握手定則鏈接

 

因此odd=2  或者  0

進一步分析:

第一:如果odd=2,則圖中隱含的那條迴路一定是歐拉回路,將歐拉回路走完,剛好滿足題目中的條件(回到原點且每條邊都走過一遍)即將所有的邊權相加和,記作sum,並且是最短的,因爲只走過一遍嘛。

 

第二:如果odd=1,則我們可以通過歐拉通路從起點st走到終點ed,其中sted是度爲奇數的兩個點。由於要回到起點st,則還要求出從edst的最短路經,記作dis

那麼這是需要走的最短路程爲sum = sum + dis。求edst的最短路經可以用任意一種常規方法。但是由於題目的頂點數也就不超過26(26個小寫字母).故用On^3)的floyd是最簡單的。

 

至此全部完畢,代碼如下。

/**
   author:liuwen
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=30;
const int inf=100000000;
int G[30][30],degree[30],odd[30];
void initial_Map()
{
    memset(degree,0,sizeof(degree));
    memset(odd,0,sizeof(odd));
    for(int i=0;i<30;i++)
        for(int j=0;j<30;j++)
            G[i][j]=inf;
}
int main()
{
    //freopen("in.txt","r",stdin);
    string s,str;
    while(cin>>s){
        int sum=0,w,u,v;
        initial_Map();
        w=s.size();
        sum+=w;
        u=s[0]-'a';
        v=s[s.size()-1]-'a';
        G[u][v]=w;
        G[v][u]=w;
        degree[u]++;
        degree[v]++;
        while(cin>>str){
            if(str=="deadend")  break;
            w=str.size();
            u=str[0]-'a';
            v=str[str.size()-1]-'a';
            degree[u]++;
            degree[v]++;
            G[u][v]=w;
            G[v][u]=w;
            sum+=w;
        }
        int cnt=0;
        for(int i=0;i<maxn;i++){
            if(degree[i]&°ree[i]%2==1){
                odd[cnt++]=i;
            }
        }
        //cout<<sum<<endl;
        if(cnt==0){     //如果度爲奇數的頂點數爲0
            printf("%d\n",sum);
            continue;
        }else{         //不爲0的話,一定就是2
            for(int k=0;k<30;k++){    //floyd
                for(int i=0;i<30;i++){
                    for(int j=0;j<30;j++){
                        G[i][j]=min(G[i][k]+G[k][j],G[i][j]);
                    }
                }
            }
            sum+=G[odd[0]][odd[1]];   //sum再加上從終點到起點的最短距離
            printf("%d\n",sum);
        }


    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章