POJ 3169 Layout 差分约束

本文深入探讨了差分约束的概念及其在解决数学问题时的运用,特别关注如何通过构建反向边求最短路来解决最小值问题,以及直接求最短路来解决最大值问题。通过实例分析,详细阐述了两种情况下的求解策略及代码实现。

做了这道题目感觉对差分约束的理解又加深了一些。

关于差分约束最后要求的值是最大值还是最小值的问题,求最小值的时候可以反向建边求最短路,也可以转化成a-b>=x的约束然后求最长路。求最大值的时候可以直接求最短路,如果目标距离是INF的话就代表可以任意长。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <string>
#include <iostream>
#include <map>
#include <cstdlib>
#include <list>
#include <set>
#include <queue>
#include <stack>

using namespace std;

typedef long long LL;
const int maxn = 10000 + 5;
const int maxm = 500000 + 5;
const int INF = INT_MAX / 4;
int first[maxn],nxt[maxm],d[maxn],v[maxm],w[maxm];
int N,ML,MD,qcnt[maxn],ecnt;
bool inq[maxn];

void adde(int _u,int _v,int _w) {
    //printf("adde %d %d %d\n",_u,_v,_w);
    v[ecnt] = _v;   w[ecnt] = _w;
    nxt[ecnt] = first[_u];
    first[_u] = ecnt;
    ecnt++;
}

void solve() {
    bool bad = false;
    for(int i = 0;i <= N;i++) {
        d[i] = INF;
        inq[i] = false;
        qcnt[i] = 0;
    }
    d[1] = 0;
    inq[1] = true;
    queue<int> q;
    q.push(1);
    qcnt[1] = 1;
    while(!q.empty() && !bad) {
        int x = q.front(); q.pop();
        inq[x] = false;
        for(int i = first[x];i != -1;i = nxt[i]) {
            if(d[v[i]] > d[x] + w[i]) {
                d[v[i]] = d[x] + w[i];
                if(!inq[v[i]]) {
                    q.push(v[i]);
                    inq[v[i]] = true;
                    qcnt[v[i]]++;
                    if(qcnt[v[i]] > N + 1) {
                        bad = true; break;
                    }
                }
            }
        }
    }
    //for(int i = 0;i <= N;i++) printf("%d ",d[i]); putchar('\n');
    //for(int i = 0;i <= N;i++) printf("%d ",qcnt[i]); putchar('\n');
    if(bad == true) puts("-1");
    else if(d[N] >= INF) puts("-2");
    else printf("%d\n",d[N]);
}

int main() {
    while(~scanf("%d%d%d",&N,&ML,&MD)) {
        ecnt = 0;
        memset(first,-1,sizeof(first));
        memset(nxt,-1,sizeof(nxt));
        for(int i = 1;i <= ML;i++) {
            int a,b,c; scanf("%d%d%d",&a,&b,&c);
            adde(a,b,c);
        }
        for(int i = 1;i <= MD;i++) {
            int a,b,c; scanf("%d%d%d",&a,&b,&c);
            adde(b,a,-c);
        }
        for(int i = 1;i <= N;i++) {
            adde(i,i - 1,0);
        }
        solve();
    }
    return 0;
}

  

转载于:https://www.cnblogs.com/rolight/p/3859844.html

根据原作 https://pan.quark.cn/s/459657bcfd45 的源码改编 Classic-ML-Methods-Algo 引言 立这个项目,是为了梳理和总结传统机器学习(Machine Learning)方法(methods)或者算法(algo),和各位同仁相互学习交流. 现在的深度学习本质上来自于传统的神经网络模型,很大程度上是传统机器学习的延续,同时也在不少时候需要结合传统方法来实现. 任何机器学习方法基本的流程结构都是通用的;使用的评价方法也基本通用;使用的一些数学知识也是通用的. 本文在梳理传统机器学习方法算法的同时也会顺便补充这些流程,数学上的知识以供参考. 机器学习 机器学习是人工智能(Artificial Intelligence)的一个分支,也是实现人工智能最重要的手段.区别于传统的基于规则(rule-based)的算法,机器学习可以从数据中获取知识,从而实现规定的任务[Ian Goodfellow and Yoshua Bengio and Aaron Courville的Deep Learning].这些知识可以分为四种: 总结(summarization) 预测(prediction) 估计(estimation) 假想验证(hypothesis testing) 机器学习主要关心的是预测[Varian在Big Data : New Tricks for Econometrics],预测的可以是连续性的输出变量,分类,聚类或者物品之间的有趣关联. 机器学习分类 根据数据配置(setting,是否有标签,可以是连续的也可以是离散的)和任务目标,我们可以将机器学习方法分为四种: 无监督(unsupervised) 训练数据没有给定...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值