Poj 3411 Paid Roads【Dfs】

Paid Roads
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 6876 Accepted: 2552

Description

A network of m roads connects N cities (numbered from 1 to N). There may be more than one road connecting one city with another. Some of the roads are paid. There are two ways to pay for travel on a paid road i from city ai to city bi:

  • in advance, in a city ci (which may or may not be the same as ai);
  • after the travel, in the city bi.

The payment is Pi in the first case and Ri in the second case.

Write a program to find a minimal-cost route from the city 1 to the city N.

Input

The first line of the input contains the values of N and m. Each of the following m lines describes one road by specifying the values of aibiciPiRi (1 ≤ ≤ m). Adjacent values on the same line are separated by one or more spaces. All values are integers, 1 ≤ m, N ≤ 10, 0 ≤ Pi , Ri ≤ 100, Pi ≤ Ri (1 ≤ ≤ m).

Output

The first and only line of the file must contain the minimal possible cost of a trip from the city 1 to the city N. If the trip is not possible for any reason, the line must contain the word ‘impossible’.

Sample Input

4 5
1 2 1 10 10
2 3 1 30 50
3 4 3 80 80
2 1 2 10 10
1 3 2 10 50

Sample Output

110

Source

Northeastern Europe 2002, Western Subregion

题目大意:

要从节点1出发,目标点是节点N,如果从a走到b之前走过了c,那么支付p的花费,否则支付r的花费,问从起点到达终点的最小花费。


思路:


1、首先考虑到N,M都是比较小的一个数量级,我们可以考虑暴搜。


2、接下来我们考虑一个点最多可以经过多少次的问题。对应一共最多有十条边,假设我们走的路程是这样才能达到最优:

1->2->1->3->1->4->1->5->1->n.

那么点1最多可能会经过五次,那么我们控制每个点的最多可能经过次数为5即可。


Ac代码:

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
struct node
{
    int from;
    int to;
    int p;
    int r;
    int c;
    int next;
}e[5115];
int cont,n,m,output;
int head[15];
int vis[15];
void add(int from,int to,int c,int p,int r)
{
    e[cont].to=to;
    e[cont].c=c;
    e[cont].p=p;
    e[cont].r=r;
    e[cont].next=head[from];
    head[from]=cont++;
}
void Dfs(int u,int sum)
{
    vis[u]++;
    if(u==n)
    {
        output=min(output,sum);
        return ;
    }
    else
    {
        for(int i=head[u];i!=-1;i=e[i].next)
        {
            int v=e[i].to;
            int tmp;
            if(vis[e[i].c]>0)tmp=e[i].p;
            else tmp=e[i].r;
            if(vis[v]<=4)
            {
                Dfs(v,sum+tmp);
                vis[v]--;
            }
        }
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        cont=0;
        memset(head,-1,sizeof(head));
        for(int i=0;i<m;i++)
        {
            int x,y,c,p,r;
            scanf("%d%d%d%d%d",&x,&y,&c,&p,&r);
            add(x,y,c,p,r);
        }
        output=0x3f3f3f3f;
        memset(vis,0,sizeof(vis));
        Dfs(1,0);
        if(output==0x3f3f3f3f)printf("impossible");
        else
        printf("%d\n",output);
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值