POJ 1062 【带约束的最短路问题】

中文题题意不写。

建图:

我自己想到的建图方式是把每个物品看作两个点,编号分别是i和i+n,然后每个物品两个点之间边的权值是物品本身的价值。然后从第i个点往外连边,目标是可替代品顶点编号较小的点,权值为替代之后的优惠费用,然后将可替代品的顶点编号较大的点连向第i+n个顶点,权值是0.

这种建图方法将点的数量增加为原来的两倍,边的数量也相应增加,所以并不是好的建图方法。

大牛的建图方法是把旅行家看作是一个顶点,边的出路是每个物品,权值是每个物品对应的价值,然后当有物品可以有替代物品的时候,连边,起点是替代物,终点是被替代物品,权值是替代后的优惠价格。

这种建图方法更加稠密,同时节点的数量也少。

这道题需要注意的是连接是单向边。

对于约束的处理是,参考了大牛的思想。从第一个节点枚举到第n个节点,以该节点的等级为最低等级,以该节点加m为最高等级,将在这个范围以外的顶点做vis=1的处理,反复进行最短路,取这些最短路的最小值。

#include<stdio.h>
#include<string.h>
int max(int a,int b)
{
    if(a>b)
        return a;
    return b;
}
int min(int a,int b)
{
    if(a<b)
        return a;
    return b;
}
int m,n;
int dis[205];
bool vis[205];
const int inf=999999999;
int deg[205];
int ednum;
struct edge
{
    int id,w;
    edge *next;
};
edge *adj[205];
edge edges[5005];
inline void addEdge(int a,int b,int c)
{
    edge *tmp;
    tmp=&edges[ednum];
    ednum++;
    tmp->id=b;
    tmp->w=c;
    tmp->next=adj[a];
    adj[a]=tmp;
}
void solve(int pos)
{
    vis[pos]=1;
    for(edge *p=adj[pos]; p; p=p->next)
    {
        if((!vis[p->id]))
        {
            if((p->w)+dis[pos]<dis[p->id])
            {
                dis[p->id]=(p->w)+dis[pos];
            }
        }
    }
    int next=inf;
    int minn=inf;
    for(int i=1; i<=2*n; i++)
    {
        if(!vis[i]&&minn>dis[i])
        {
            minn=dis[i];
            next=i;
        }
    }
    if(next<=2*n)
    {
        solve(next);
    }
}
int main()
{
    int num,id,tmon,up,low;
    int aa,bb,cc,dd;
    int rel=inf;
    scanf("%d%d",&m,&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%d%d%d",&aa,&bb,&cc);
        addEdge(i,i+n,aa);
        deg[i]=deg[i+n]=bb;
        for(int  j=1; j<=cc; j++)
        {
            scanf("%d%d",&id,&tmon);
            addEdge(i,id,tmon);
            addEdge(id+n,i+n,0);
        }
    }
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=2*n; j++)
        {
            dis[j]=inf;
        }
        for(int j=1; j<=2*n; j++)
        {
            if(deg[j]>=deg[i]&&deg[j]<=deg[i]+m)
            {
                vis[j]=0;
            }
            else
            {
                vis[j]=1;
            }
        }
        dis[1]=0;
        solve(1);
        if(rel>dis[1+n])
            rel=dis[1+n];
    }
    printf("%d\n",rel);
    return 0;
}
时间: 2024-10-20 14:46:20

POJ 1062 【带约束的最短路问题】的相关文章

POJ - 1062昂贵的聘礼最短路或者DFS

POJ - 1062 昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %I64d & %I64u Submit Status Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币.如

POJ 1062 昂贵的聘礼 最短路

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

poj 1062 -- 昂贵的聘礼

昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 35515   Accepted: 10163 Description 年 轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿 不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币.如果你能够弄来他的水晶球,那么只要 5

poj 1062 昂贵的聘礼 解题报告

题目链接:http://poj.org/problem?id=1062 这一题只要想到如何建图,就不太难解决了.假设对于编号为 i 的物品,如果它得到物品 j 后价格从 pricei 降低到 pricej 的话,就用一个cost[i][j] = pricej.也就是从物品 i 到物品 j 连一条有向边.每一个编号的物品都这样处理,然后套用dijk 算法,求出从每个点出发的最短路,最终最小的那个就是答案.考虑到等级限制,别人可以跟酋长接触的前提是这个人的等级在 [ level 酋长-m  ~ le

【POJ 1062】 昂贵的聘礼

[POJ 1062] 昂贵的聘礼 附加一个小判断的最短路 这个题配得上这标题...有一个弯确实不好拐 反正我开始没想出来 然后居然水过去了!! 没错 POJ这数据... 很久前做的 最近根据计划训练又翻出来 看了看discussion 发现两组数据WA 重新想了想 改成了正规做法 其实就是由一号物品(首领物品/目标物品)的地位 向上 向下延伸出了一段可交易地位的范围 [level[1]-m, level[1]+m] 而要令一条路中所有点都符合条件 只需要每两点间距离不超过地位限制 即不断枚举区间

POJ -1062 昂贵的聘礼(前向星 &amp;&amp; SPFA)

题目链接:昂贵的聘礼 这个题对自己收获挺大的,模板要自己经常敲,才能理解,要自己经常敲,从能温故而知新,自己以前总结的建图方式,做题的时候要会用,要敢用,否则==NULL. 题意对于交换条件描述的有点不清楚,这里解释一下,假设8件物品,等级差距不能超过3,酋长LV 5,所以可以进行交换的LV区间是[2,5][3,6][4,7][5,8],不必考虑题目那一句,"但是如果他和某个地位较低的人进行了交易,地位较高的的人不会再和他交易,他们认为这样等于是间接接触,反过来也一样".越看越晕,只要

带约束的最优化问题

支持向量机SVM的训练过程中需要求解带约束的最优化问题. 带约束的最优化问题通常表述如下: objective:minw f(w)s.t. {gi(w)≤0,hj(w)=0,i=1,2,3...n;j=1,2,3...m;不等式约束等式约束 gi(w),hj(w)和f(w)一般都是连续可导的.要求在满足gi(w)≤0,hj(w)=0的前提下求能使得目标函数f(w)最小化的w. 学习支持向量机SVM时,拉格朗日对偶.Slater条件.KKT条件等一大堆概念席卷而来,让没系统学习过凸优化的笔者一头雾

poj 3169 差分约束

3169 差分约束的是满足多组形如xi-yj<=bk{i,j<n k<m}不等式极值问题,可以转化为单源最短路来求. 在最短路中 d[v]<=d[u]+w(u,v) 可以看出跟上面的不等式很像 通常有两种一种是求满足所有不等式的最大值,还有是最小值. 这篇博客可以参考一下 分析: 题目给出了两种不等式  d[u]+dl >=d[v]       d[u]+dd<=d[v]  要求的是最大值,也就是最短路 对于d[u]+dl>=d[v] 建边(u,vdl) 对于d[

用二次规划法解带约束的线性回归

对于解带约束(线性约束)的线性回归通常的办法是,将约束直接表示在线性回归中,也就是减少一个变量(即回归到线性约束本身的自由变量数目).然而今天由于要解一个问题发现了另一种思路的解法,是比变换变量更为通用的办法,就是用二次规划法解带约束的线性回归. 二次规划法有如下一般形式: 各个部分为: 特别地如果约束条件为等号,则可以用拉格朗日乘子法直接求解.如果Q是不定矩阵,甚至有一个特征值是负数的,问题就是NP难问题.. 解决一个带约束的线性回归问题,形如: 需要求解最小化: 这个式子展开来写成矩阵形式就