zoj2027Travelling Fee(Spfa+枚举)

题目链接:

huangjing

题意:

给了起始和终点城市,然后给了若干对城市和距离,然后从起点到终点最小的费用,但是有一个新优惠,那就是费用最大的两个城市之间可以免费。

思路:

最开始以为求了最短路然后减去最大的费用即可。但是想了一组样例就知道是错的。

比如1--->2---->3 然后有直接1----->3,那么如果按刚才的思路,那么最小费用就是2

2     5                  8

所以思路是错的。。然后在cp的帮助下得知,既然不知道哪条是最大的费用路,那么我们就对每条路进行枚举,假设这条是最长路。。然后做n次spfa,取最小值。。。。

题目:

Travelling Fee


Time Limit: 2 Seconds      Memory Limit: 65536 KB



Samball is going to travel in the coming vacation. Now it‘s time to make a plan. After choosing the destination city, the next step is to determine the travel route. As this poor guy
has just experienced a tragic lost of money, he really has limited amount of money to spend. He wants to find the most costless route. Samball has just learned that the travel company will carry out a discount strategy during the vacation: the most expensive
flight connecting two cities along the route will be free. This is really a big news.

Now given the source and destination cities, and the costs of all the flights, you are to calculate the minimum cost. It is assumed that the flights Samball selects will not have any
cycles and the destination is reachable from the source.

Input

The input contains several test cases, each begins with a line containing names of the source city and the destination city. The next line contains an integer m (<=100), the number of flights, and then m lines follow, each contains names of the source city
and the destination city of the flight and the corresponding cost. City names are composed of not more than 10 uppercase letters. Costs are integers between 0 to 10000 inclusively.

Process to the end of file.

Output

For each test case, output the minimum cost in a single line.

Sample Input

HANGZHOU BEIJING

2

HANGZHOU SHANGHAI 100

SHANGHAI BEIJING 200

Sample Output

100

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
#include<cmath>
#include<string>
#include<queue>
#define eps 1e-9
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=100+10;
const int maxm=maxn*2+10;

map<string,bool>Judge;
map<string,int>mp;

struct Edge
{
    int to,val,next;
}edge[maxn],temp[maxn];

int st,en,n,m,cnt,cal;
int dis[maxm],head[maxm];
bool vis[maxm];
char start[maxm],End[maxm];

queue<int>Q;

int Spfa(int k)
{
    while(!Q.empty())  Q.pop();
    memset(vis,false,sizeof(vis));
    memset(dis,0x3f,sizeof(dis));
    for(int i=1;i<=cnt;i++)
        temp[i]=edge[i];
    temp[k].val=0;
    dis[1]=0;
    vis[1]=true;
    Q.push(1);
    while(!Q.empty())
    {
        int Gery=Q.front();
        Q.pop();
        for(int i=head[Gery];i!=-1;i=temp[i].next)
        {
            int small_milan=temp[i].to;
            int val=temp[i].val;
            if(dis[small_milan]>dis[Gery]+val)
            {
                dis[small_milan]=dis[Gery]+val;
                if(!vis[small_milan])
                {
                    vis[small_milan]=true;
                    Q.push(small_milan);
                }
            }
        }
    }
    return dis[2];
}

void add_edge(int x,int y,int val)
{
    edge[++cnt].to=y;
    edge[cnt].val=val;
    edge[cnt].next=head[x];
    head[x]=cnt;
}

void read_Graph()
{
    int w;
    memset(head,-1,sizeof(head));
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%s%s%d",start,End,&w);
        if(!Judge[start])
        {
            Judge[start]=true;
            mp[start]=++cal;
        }
        if(!Judge[End])
        {
            Judge[End]=true;
            mp[End]=++cal;
        }
        add_edge(mp[start],mp[End],w);
        add_edge(mp[End],mp[start],w);
    }
}

int main()
{
    while(~scanf("%s%s",start,End))
    {
        Judge.clear();
        mp.clear();
        cal=cnt=0;
        Judge[start]=true;
        Judge[End]=true;
        mp[start]=++cal;
        mp[End]=++cal;
        read_Graph();
        int ans=INF;
        for(int i=1;i<=cnt;i++)
            ans=min(ans,Spfa(i));
        printf("%d\n",ans);
    }
    return 0;
}

/*
a b
3
a b 2
b c 5
a c 8
*/

时间: 2024-10-24 04:14:33

zoj2027Travelling Fee(Spfa+枚举)的相关文章

Zoj 3088 Easter Holidays SPFA+枚举

其实就是枚举最高点和起点,然后以最高点为源点在两张图上分别做spfa.一遍最短路,一遍最长路. 暴露出来的问题:思维不够清晰,代码能力还不够 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include &

HDU - 3499 Flight 双向SPFA+枚举中间边

Flight Recently, Shua Shua had a big quarrel with his GF. He is so upset that he decides to take a trip to some other city to avoid meeting her. He will travel only by air and he can go to any city if there exists a flight and it can help him reduce

hdu3986 spfa+枚举

这题让我第一次感受到了什么叫做在绝望中A题.这题我总共交了18次,TLE不知道几次,WA也不知道几次. 这题不能用dijkstra,用这个我一直超时(我没试过dij+优先队列优化,好像优先队列优化后可以过).. 用了我近一天的时间...... #include<stdio.h> #include<queue> #include<string.h> using namespace std; #define maxn 1002 #define INF 99999999 st

【BZOJ3669】【NOI2014】魔法森林 (spfa动态队列加点算法)

3669: [Noi2014]魔法森林 Time Limit: 30 Sec  Memory Limit: 512 MB Submit: 254  Solved: 140 [Submit][Status] Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节点1,隐士则住在号节点N.小E需要通过这一片魔法森林,才能够拜访到隐士. 魔法森林中居住了一些

POJ1062 昂贵的聘礼(带限制的spfa)

Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币.如果你能够弄来他的水晶球,那么只要5000金币就行了."探险家就跑到大祭司那里,向他要求皮袄或水晶球,大祭司要他用金币来换,或者替他弄来其他的东西,他可以降低价格.探险家于是又跑到其他地方,其他人也提出了类似的要求

ACM/ICPC 之 Floyd练习六道(ZOJ2027-POJ2253-POJ2472-POJ1125-POJ1603-POJ2607)

以Floyd解法为主的练习题六道 ZOJ2027-Travelling Fee //可免去一条线路中直接连接两城市的最大旅行费用,求最小总旅行费用 //Time:0Ms Memory:604K #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; #define MAX 205 #define MAXS 12 #define

Day 9.5

T1 可以证明每个点只会走一次 如果遇到环就在环的开始点打上标记 找到可行路的时候回溯,如果回溯时碰到有标记的点就输出Infinity!,否则直接输出ans就行 1 #include <cstdio> 2 int n,a[100010],b[100010],use[100010],in[100010],flag=0,incircle[100010]; 3 char ans[100010]; 4 int dfs(int x,int dep) 5 { 6 if (x<0||x>n-1)

hdu 2962 题解

题目 题意 给出一张图,每条道路有限高,给出车子的起点,终点,最高高度,问在保证高度尽可能高的情况下的最短路,如果不存在输出 $ cannot ?reach ?destination $ 跟前面 $ hdu5418 $ 一样的,题目挺基础的,但是在细节方面比较抠.要是最高度尽可能高,我们就可以想去枚举可能的高度去跑 $ spfa $ ,但我们可以发现这样效率太低了,那么我们为什么不二分答案呢?给出最高高度了,最低不就是 $ 0 $ 吗?二分答案再去跑 $ spfa $ 加上限制条件. 这题时限

ZOJ1027 Travelling Fee(DP+SPFA)

给一张有向无环图,边都有花费,从某点到某点走的那条路径上的那一条花费最多的边可以省掉,问从起点到终点的最少花费的多少, 往DP想的话,就可以写出这个状态dp[u][mx],表示到达u点已经省掉的花费为mx的最少花费. 用SPFA更新转移方程..或者理解成队列+我为人人的转移..其实这题这样子也能解有环图. 看了别人博客,发现还有三种解法: 枚举每一条边作为省掉的边,n次SPFA.这方法简洁,可惜想不出= = 跑Dijkstra,根据记录到每一点时的最长边更新,正确性不懂.. Floyd+DP:加