#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
struct node
{
    int v,z,d,next;//存可以连接的点,用next存邻接表
}a[10010];
struct road
{
    int u,cnt,dis;//dis储存当前需要的钱数,即最短路算法里的权,u储存顶点,cnt储存组合数即状态压缩dp
    road(int uu,int cntt,int diss)
    {
        u=uu;
        cnt=cntt;
        dis=diss;
    }
    bool operator < (const road &x)const
    {
        return dis>x.dis;//将费用小的放在前面
    }
};
int first[110],co1[110],co2[110],employ[10],d[110][20000],re[10];//re储存传话人物的使用次数
int n,m,cc,len;
void bellman_ford()
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<employ[m];j++)
        {
            d[i][j]=inf;//初始化
        }
    }
    d[0][0]=0;
    priority_queue<road>q;
    q.push(road(0,0,0));
    while(!q.empty())
    {
        road qq=q.top();
        q.pop();
        if(qq.dis>d[qq.u][qq.cnt])//已经是更优的解,无需松弛
            continue;
        if(qq.u==n-1)//松弛到达n-1
        {
            printf("%d\n",qq.dis);
            return;
        }
        for(int i=first[qq.u];i!=-1;i=a[i].next)//搜寻邻接表
        {
            int tmp=qq.cnt;
            for(int j=0;j<m;j++)//更新每一个employee在这条路上的使用次数
            {
                re[j]=tmp%3;
                tmp/=3;
            }
            int v=a[i].v;
            int z=a[i].z;
            int cost=a[i].d;
            int t=1;
            if(re[z]==1)
            {
                cost+=co1[z];
            }
            else if(re[z]==2)
            {
                cost+=co2[z];
                t=0;
            }
            if(d[v][qq.cnt+t*employ[z]]>qq.dis+cost)//最短路算法的核心
            {
                d[v][qq.cnt+t*employ[z]]=qq.dis+cost;
                q.push(road(v,qq.cnt+t*employ[z],d[v][qq.cnt+t*employ[z]]));
            }
        }
    }
    printf("-1\n");
}
void add_edge(int u,int v,int z,int d)
{
    a[len].v=v;
    a[len].z=z;
    a[len].d=d;
    a[len].next=first[u];
    first[u]=len++;
}
int main()
{
    employ[0]=1;
    for(int i=1;i<=9;i++)
    {
        employ[i]=3*employ[i-1];//初始化
    }
    while(~scanf("%d%d%d",&n,&m,&cc))
    {
        memset(first,-1,sizeof(first));
        for(int i=0;i<m;i++)
        {
            scanf("%d",&co1[i]);
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d",&co2[i]);
        }
        len=0;
        int x,y,z,d;
        for(int i=0;i<cc;i++)
        {
            scanf("%d%d%d%d",&x,&y,&z,&d);
            add_edge(x,y,z,d);
        }
        bellman_ford();//可以求负权的最短路算法
    }
    return 0;
}

//思路仍待跟进

bellman的核心代码只有4行
for(int k=1;k<=n-1;k++)//进行n-1次松弛
for(int i=1;i<=m;i++)//枚举每一条边
if(dis[v[i]]>dis[u[i]]+w[i])//尝试松弛每一条边
dis[v[i]]=dis[u[i]]+w[i];
这个算法也是遍历n-1遍找过所有的点,至于为什么是n-1呢。dijs算法n-1次遍历是因为有n-1个点需要遍历,这个也是因为最短路是一个不包含回路的路径,无论正负权回路都不能有,那么去掉回路,n个点任意两点之间就最多有n-1条边。但是程序可能在不到n-1次循环就已经找到了所有最短路,说明这个是最坏情况下是n-1次遍历。
dis同样是存在起始点到各个顶点的最短路,这个与dijs不同的是,dijs每次找到最近的点进行松弛操作,而这个bellman则是只要路程更短我就松弛。也是因为这样才能用来解决负权值问题。
那么怎么来看有负权值回路呢,如果有负权值回路,那最短路就不会存在,因为最短路会越来与小。那么在n-1轮松弛后,要是还能松弛就代表有负权值回路。

2010辽宁省赛E(Bellman_Ford最短路,状态压缩DP【三进制】)的更多相关文章

  1. HDU 3001 Travelling(状态压缩DP+三进制)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题目大意:有n个城市,m条路,每条路都有一定的花费,可以从任意城市出发,每个城市不能经过两次以上 ...

  2. Light OJ 1316 A Wedding Party 最短路+状态压缩DP

    题目来源:Light OJ 1316 1316 - A Wedding Party 题意:和HDU 4284 差点儿相同 有一些商店 从起点到终点在走过尽量多商店的情况下求最短路 思路:首先预处理每两 ...

  3. 最短路+状态压缩dp(旅行商问题)hdu-4568-Hunter

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4568 题目大意: 给一个矩阵 n*m (n m<=200),方格里如果是0~9表示通过它时要花 ...

  4. POJ 3311 Hie with the Pie (BFS+最短路+状态压缩)

    题意:类似于TSP问题,只是每个点可以走多次,求回到起点的最短距离(起点为点0). 分析:状态压缩,先预处理各点之间的最短路,然后sum[i][buff]表示在i点,状态为buff时所耗时...... ...

  5. 2021蓝桥杯省赛C++A组试题E 回路计数 状态压缩DP详细版

    2021蓝桥杯省赛C++A组试题E 回路计数 状态压缩DP 题目描述 蓝桥学院由21栋教学楼组成,教学楼编号1到21.对于两栋教学楼a和b,当a和b互质时,a和b之间有一条走廊直接相连,两个方向皆可通 ...

  6. HDU 4511 (AC自动机+状态压缩DP)

    题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=4511 题目大意:从1走到N,中间可以选择性经过某些点,比如1->N,或1->2-> ...

  7. HDU 3681 Prison Break(状态压缩dp + BFS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 前些天花时间看到的题目,但写出不来,弱弱的放弃了.没想到现在学弟居然写出这种代码来,大吃一惊附加 ...

  8. [转]状态压缩dp(状压dp)

    状态压缩动态规划(简称状压dp)是另一类非常典型的动态规划,通常使用在NP问题的小规模求解中,虽然是指数级别的复杂度,但速度比搜索快,其思想非常值得借鉴. 为了更好的理解状压dp,首先介绍位运算相关的 ...

  9. BFS+状态压缩DP+二分枚举+TSP

    http://acm.hdu.edu.cn/showproblem.php?pid=3681 Prison Break Time Limit: 5000/2000 MS (Java/Others)   ...

随机推荐

  1. mybatis学习(四)

    创建mybatis工程 工程目录: 具体步骤: 1.创建sqlMapConfig.xml文件,配置mybatis的运行环境,事物,数据源,加载mapper映射文件等. 2.创建po类(查询或者返回的属 ...

  2. vue2.0 构建单页应用最佳实战

    vue2.0 构建单页应用最佳实战   前言 我们将会选择使用一些 vue 周边的库vue-cli, vue-router,vue-resource,vuex 1.使用 vue-cli 创建项目2.使 ...

  3. 常见ETL工具一览,你知多少?

    这些年,几乎都与ETL打交道,接触过多种ETL工具.现将这些工具做个整理,与大家分享. 一 ETL工具[国外] 1. datastage点评:最专业的ETL工具,价格不菲,使用难度一般 下载地址:ft ...

  4. 在Win8.1系统下如何安装运行SQL Server 2005

    按正常情况,在Win8/Win8.1系统下安装微软的SQL Server 2005套件会存在兼容问题,即使安装完,最后的结果就是导致其服务项无法正常启动. 如果用户创建使用的项目非要按照SQL Ser ...

  5. 分享知识-快乐自己:反射机制Demo解析

    Java-Reflect专题 基本反射简介: 1):JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象能够调用它的任意方法和属性;这种动态获取信息以及动 ...

  6. 九 Django框架,Form表单验证

    表单提交 html <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  7. 关于MFC消息的总结

    一.MFC的消息类型 MFC的消息类型大致可以分为三种: 1.命令消息.由菜单和工具栏或快捷键产生,以WM_COMMAND形式发出(以WM_COMMAND发出的还有很多控件,如Button等,但它们产 ...

  8. python 标准库 —— http(http.cookiejar)

    1. cookie 信息的读取 from urllib import request import http from http import cookiejar cookie = cookiejar ...

  9. ACM学习历程—HDU5587 Array(数学 && 二分 && 记忆化 || 数位DP)(BestCoder Round #64 (div.2) 1003)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5587 题目大意就是初始有一个1,然后每次操作都是先在序列后面添加一个0,然后把原序列添加到0后面,然后 ...

  10. 清理:db上面的过期的binlog,释放磁盘空间。 (转)

    如果10台以内的db的话,自己手动ssh进去,clean就足以,但是上百台呢,就要写脚本了.大概思路:在 一台db跳转机上面, 写一个脚本,访问slave,远程获取正在复制的master上面的binl ...