The Postal Worker Rings Once(UVA 117)最短路径—SPFA算法+邻接表

The Postal Worker Rings Once

From:UVA,
117

Time Limit: 3000 MS


Background

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 K?nigsberg 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.

The Problem

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.

The 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.

The 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

题目大意:

每个字符串的首字母和尾字母代表街道的两个路口,是双向的,字符串的长度是街道的长度,邮递员需要穿过所有的街道,求邮递员走的最短路径。

解题思路:

当所有点的入度都是偶数说明成环,直接所有边的边长相加即可。若有奇数度 ,则是所有边长相加以后再加上从奇度点到奇度点的最短路径。

SPFA算法+邻接表。

代码:

#include<iostream>
#include<string>
#include<cstdio>
#include<queue>
using namespace std;

const int maxn=30;
const int maxm=4000000;

struct edge{
    int u,v,w,next;
    edge(int u0=0,int v0=0,int w0=0,int next0=0){
        u=u0,v=v0,w=w0,next=next0;
    }
}e[maxm];

string str0;
int dist[maxn],head[maxn],indeg[maxn],cnt,sumDist,from,des;
bool isInQueue[maxn];

void initial(){
    from=des=0;
    cnt=0;
    sumDist=0;
    for(int i=0;i<maxn;i++){
        dist[i]=1<<30;//不要写成31,不然就爆掉了。
        head[i]=-1;
        isInQueue[i]=false;
        indeg[i]=0;
    }
}

void adde(int u,int v,int w){
    e[cnt].u=u,e[cnt].v=v,e[cnt].w=w;
    e[cnt].next=head[u],head[u]=cnt++;//邻接表储存图。
}

void input(){
    while(str0!="deadend"){
        int p=str0[0]-'a',q=str0[str0.length()-1]-'a';
        indeg[p]++;
        indeg[q]++;
        adde(p,q,str0.length());
        adde(q,p,str0.length());//双向边
        sumDist+=str0.length();
        cin>>str0;
    }
}

void outResult(){printf("%d\n",sumDist);}

void spfa(){
    queue <int> q;
    int s;
    dist[from]=0;
    q.push(from);
   // cntIn[from]++;
    isInQueue[from]=true;
    while(!q.empty()){
        s=q.front();
        q.pop();
        for(int i=head[s];i!=-1;i=e[i].next){
            if(dist[e[i].v]>dist[e[i].u]+e[i].w){
                dist[e[i].v]=dist[e[i].u]+e[i].w;
                if(!isInQueue[e[i].v]){
                    q.push(e[i].v);
                    //cntIn[e[i].v]++;
                    //if(cntIn[e[i].v]>sqrt(n)) return;//判是否负环。
                    isInQueue[e[i].v]=true;
                }
            }
        }
        isInQueue[s]=false;
    }
}

void solve(){
    bool isOdd=false;
    for(int i=0;i<26;i++){
        if(indeg[i]&1&&!isOdd){
            isOdd=true;
            from=i;
            continue;
        }
        if(indeg[i]&1&&isOdd){des=i;break;}
    }
    if(!isOdd) return;
    spfa();
    sumDist+=dist[des];
}

int main(){
    while(cin>>str0){
        initial();
        input();
        solve();
        outResult();
    }
    return 0;
}

Problem B : The Postal Worker Rings Once

From:UVA,
117

Submit

Time Limit: 3000 MS


Background

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 K?nigsberg 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.

The Problem

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.

The 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.

The 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
时间: 2024-10-08 02:32:37

The Postal Worker Rings Once(UVA 117)最短路径—SPFA算法+邻接表的相关文章

最短路径——SPFA算法

一.前提引入 我们学过了Bellman-Ford算法,现在又要提出这个SPFA算法,为什么呢? 考虑一个随机图(点和边随机生成),除了已确定最短路的顶点与尚未确定最短路的顶点之间的边,其它的边所做的都是无用的,大致描述为下图(分割线以左为已确定最短路的顶点): 其中红色部分为所做无用的边,蓝色部分为实际有用的边.既然只需用到中间蓝色部分的边,那就是SPFA算法的优势之处了. 二.算法描述 算法特点:在 Bellman-ford 算法的基础上加上一个队列优化,减少了冗余的松弛操作,是一种高效的最短

最短路径--SPFA 算法

适用范围:给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了. 我们约定有向加权图G不存在负权回路,即最短路径一定存在.当然,我们可以在执行该算法前做一次拓扑排序,以判断是否存在负权回路,但这不是我们讨论的重点. 算法思想:我们用数组d记录每个结点的最短路径估计值,用邻接表来存储图G.我们采取的方法是动态逼近法:设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计

【HDU 1874 2544 2066 2112】 Dijkstra单源最短路径专题 —— 优先队列+邻接表/邻接矩阵

HDU 1874  畅通工程续 解题报告: 由于顶点(城镇)的数目只有200个,所以可以采用邻接矩阵的形式来存储,代码会更简洁些,也不容易出错.但是处于练习的目的,采用邻接表+优先队列的方式实现,优先队列使用STL中的priority_queue.很基础的单源单汇最短路径. HDU 2544  最短路 解题报告: 基本和1874是一样的,只是数据量小了,并且要求当n==0 && m==0时终止,值得注意!这道题同时也保证了一定是可达的,所以输出时可以直接输出. HDU 2066  一个人的

设计一个算法,输出从u到v的所有最短路径(采用邻接表存储)

思想:用path数组存放路径(初始为空),d表示路径长度(初始为-1),查找从顶点u到v的最短路径过程如图所示: 对应算法如下: void FindPath(AGraph *G,int u,int v,int path[ ],int d) { int w,i; ArcNode *p; d++; path[d]=u; visited[u]=1; //路径长度增1 if(u==v) { for(i=0;i<=d;i++) printf("%2d",path[i]); printf(&

最短路径——SPFA算法(C++)

源代码: #include<cstdio>#include<cstring>#include<queue>using namespace std;queue <int> h;int i[1001][1001],j[1001],n,k; //要想节省空间,会不会有更好的方法呢?bool f[1001]={0};int main(){ memset(i,0x3f,sizeof(i)); memset(j,0x3f,sizeof(j)); scanf("

hrbust1339 Touring (Dijkstra最短路径)(邻接表)

本文出自:http://blog.csdn.net/svitter 题意:两个人从c出发,分别想去a,b旅行,两个城市之间只有一条路,有一个相应的价值.求最小的价值.通行的时候只花费一个价值. 本题目的关键在于优先队列,求出a, b, c到各点的最小价值,然后从中挑选一个点作为分开的点. dijktra算法时用邻接表存储,因为明显是稀疏图..还有就是存边的时候记得存双向的边,利用优先队列弹出最小的花费.使用邻接表记得初始化node[i] = -1(可以用memset) AC: //=======

最短路径-SPFA算法

SPFA(Super Programming Festival Algorithm) 其实是 Shortest Path Faster Algorithm啦^^-o-^^ 简单介绍:复杂度只和边的数量相关,适用边的数量很少的最短路问题,BELLMAN-FORD算法的一种优化版本. 算法实现是BFS+剪枝构成的. 算法步骤: 基于BFS遍历,尝试将(p, q)加入到队尾的时候,发现队列中已经存在一个(p, q')了,那么你就可以比较q和q':如果q>=q',那么(p, q)这个节点实际上是没有继续

最短路径—Floyd算法

Floyd算法 所有顶点对之间的最短路径问题是:对于给定的有向网络G=(V,E),要对G中任意两个顶点v,w(v不等于w),找出v到w的最短路径.当然我们可以n次执行DIJKSTRA算法,用FLOYD则更为直接,两种方法的时间复杂度都是一样的. 1.定义概览 Floyd-Warshall算法(Floyd-Warshall algorithm)是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被用于计算有向图的传递闭包.Floyd-Warshall算法的时间复杂度

最短路径(四)—Bellman-Ford的队列优化(邻接表)

上一节我们写了Bellman-Ford算法解决负权边的问题: 邻接表存储图: n个顶点,m条边. 数组实现邻接表.对每一条边进行1-m编号.用u,v,w三个数组来记录每条边的信息,即u[i],v[i],w[i]表示第i条边是从第 u[i]号顶点到v[i]号顶点且权值为w[i]. first数组的1-n号单元格分别用来存储1-n号顶点的第一条边的编号,初始的时候因为没有边加入所有都是-1.即first[u[i]]保存顶点u[i]的第一条边的编号,next[i]存储"编号为i的边"的&qu