2015山东信息学夏令营 Day4T3 生产

2015山东信息学夏令营 Day4T3 生产

【题目描述】

工厂为了生产一种复杂的产品,给各个生产部门制定了详细的生产计划。那么,就经常会有生产部门要把产品送到另一个生产部门作为原料。这是一个注重产品质量的工厂,所以每当有产品要从A部门运到B部门时,都要先从A部门送到质量检验处,检验合格后再从质量检验处运到B部门。

有些部门之间有传送带连接,厂长想知道每次将产品从一个部门运送到另一个部门最少需要多长时间。

【输入格式】

第一行两个整数n、m,n表示部门数量,m表示传送带数量。出于方便,1号部门是质量检验处。

接下来m行,每行三个整数u、v、w,表示有一条从u部门到v部门的传送带,传送过去需要w个单位时间。注意传送带是单向的。

接下来一个整数q,表示有q次运送。

接下来q行,每行两个数a、b,表示这一次要将产品从a部门运送到b部门。

【输出格式】

输出q行,每行一个整数,表示这次运送最少需要的时间。若没有传送方案,输出-1。

【样例输入】

5 5

1 2 3

1 3 5

4 1 7

5 4 1

5 3 1

3

4 2

5 3

2 3

【样例输出】

10

13

-1

【数据规模与约定】

30%的数据,n≤100,m≤500,w=1

60%的数据,n≤100,m≤5000

另20%的数据,q=1

100%的数据,2≤n≤3000,m≤100000,2≤a,b≤n,

q≤100000,1≤u,v≤n,1≤w≤10000

有些部门之间可能有多条传送带。

工厂的员工都非常尽职尽责,他们的认真和热情决定了产品的完美,所以不必考虑产品不合格的情况。

思路:

1、最短路,A到1再到B的距离,等于1到B的距离加上1到A的距离

2、存者正反两个图,在反图上求1到A距离,在正图上求1到B的距离

代码:

①官方标程(spfa + 链式前向星)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 3050;
const int M = 500050;
const int inf = 987654321;
int n,m,q;
struct Edge
{
    int u,v,w;
}xu[M];
int point[N],to[M],next[M],val[M];
int dui[N],mina[N],minb[N],top,tail;
bool indui[N];
void MakeMinLen(int x[])
{
    int i;
    dui[1]=1;
    top=0;tail=1;
    indui[1]=1;
    for(i=1;i<=n;i++)
        x[i]=inf;
    x[1]=0;
    while(top^tail)
    {
        top++;
        if(top==N)
            top=0;
        int now=dui[top];
        int then=point[now];
        indui[now]=0;
        while(then)
        {
            int tox=to[then];
            if(x[tox]>x[now]+val[then])
            {
                x[tox]=x[now]+val[then];
                if(!indui[tox])
                {
                    indui[tox]=1;
                    tail++;
                    if(tail==N)
                        tail=0;
                    dui[tail]=tox;
                }
            }
            then=next[then];
        }
    }
}
void InitGraph()
{
    int i;
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;i++)
        scanf("%d%d%d",&xu[i].u,&xu[i].v,&xu[i].w);
    memset(point,0,sizeof point);
    for(i=1;i<=m;i++)
    {
        next[i]=point[xu[i].v];
        point[xu[i].v]=i;
        to[i]=xu[i].u;
        val[i]=xu[i].w;
    }
    MakeMinLen(mina);
    memset(point,0,sizeof point);
    for(i=1;i<=m;i++)
    {
        next[i]=point[xu[i].u];
        point[xu[i].u]=i;
        to[i]=xu[i].v;
        val[i]=xu[i].w;
    }
    MakeMinLen(minb);
}
void MakeAns()
{
    scanf("%d",&q);
    while(q--)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        int res=mina[a]+minb[b];
        if(res>=inf)
            res=-1;
        printf("%d\n",res);
    }
}
int main()
{
    freopen("data.in","r",stdin);
    freopen("data.out","w",stdout);
    InitGraph();
    MakeAns();
    return 0;
}

②自己写的,感觉dij快一点,一测发现比标程慢不少TAT

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define inf ~0U>>2
#define maxn 3005
using namespace std;
struct orz{
    int d;
    int p;
    friend bool operator < (orz a,orz b){
        return a.d > b.d;
    }
};
struct edge{
    int v;
    int w;
};
priority_queue< orz > ss;
vector<edge> g[maxn],op[maxn];
int n,m,q,flag = 0,v[maxn],d[maxn],opd[maxn];
void init(){
    cin>>n>>m;
    int u,v,w;
    edge tmp;
    for(int i = 1;i <= m;i++){
        scanf("%d%d%d",&u,&v,&w);
        tmp.v = v;
        tmp.w = w;
        g[u].push_back(tmp);
        tmp.v = u;
        op[v].push_back(tmp);
    }
    cin>>q;
    for(int i = 1;i <= n;i++) d[i] = opd[i] = inf;
}
void dij(){
    orz tmp;
    tmp.d = 0;
    tmp.p = 1;
    opd[1] = 0;
    ss.push(tmp);
    flag++;
    int x,dd,to,wei;
    edge j;
    while(!ss.empty()){
        tmp = ss.top();
        ss.pop();
        x = tmp.p;
        dd = tmp.d;
        if(v[x] == flag) continue;
        v[x] = flag;
        for(int i = 0;i < g[x].size();i++){
            j = g[x][i];
            to = j.v;
            wei = j.w;
            if(d[to] > dd + wei){
                d[to] = dd + wei;
                tmp.d = dd + wei;
                tmp.p = to;
                ss.push(tmp);
            }
        }
    }
}
void opdij(){
    orz tmp;
    tmp.d = 0;
    tmp.p = 1;
    opd[1] = 0;
    ss.push(tmp);
    flag++;
    int x,dd,to,wei;
    edge j;
    while(!ss.empty()){
        tmp = ss.top();
        ss.pop();
        x = tmp.p;
        dd = tmp.d;
        if(v[x] == flag) continue;
        v[x] = flag;
        for(int i = 0;i < op[x].size();i++){
            j = op[x][i];
            to = j.v;
            wei = j.w;
            if(opd[to] > dd + wei){
                opd[to] = dd + wei;
                tmp.d = dd + wei;
                tmp.p = to;
                ss.push(tmp);
            }
        }
    }
}
void ask(){
    int u,v;
    long long dn;
    for(int i = 1;i <= q;i++){
        scanf("%d%d",&u,&v);
        dn = opd[u] + d[v];
        if(dn >= inf) cout<<-1<<endl;
        else cout<<dn<<endl;
    }
}
int main(){
    freopen("data.in","r",stdin);
    freopen("data.out","w",stdout);
    init();
    dij();
    opdij();
    ask();
    return 0;
}
时间: 2024-10-10 07:49:14

2015山东信息学夏令营 Day4T3 生产的相关文章

2015山东信息学夏令营 Day5T3 路径

问题描述: 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. 输入: 第一行包含一个正整数n,表示点数. 接下来n行,每行包含两个整数x[i],y[i](0<=x[i],y[i]<=10^9),依次表示每个点的坐标. 输出: 一个整数,即最小费用. 输入输出样例: path.in path.out 52 21 14 57 16 7 2 数据范围: 对于30%的数据,1<=n<=100: 对于60

北大信息学夏令营 游记

这是我第二次来北大,上一次是去人大参加APIO,顺便逛了下北大.感觉北京的 雾霾也没有像传说中面对面看不清脸那么夸张.印象中北大应该是环境优美充满文艺气息的圣地,但是这次没有去未名湖那边,然后才发现原来北大好破旧,感觉像个建筑工地,到处在盖楼,现代新式建筑和旧房子交错,还有杂七杂八的小吃店.有同学提出了疑问,辅导员说我们应该感到高兴,盖楼是因为要扩招,扩招就有更多的机会来北大啦.夏令营期间,我们的活动场地主要是在寝室 餐厅 和教室,仅仅是北大小小的一角,但是我已经分不清方向了...迷路了好几次,

NKOJ 2017信息学夏令营第1场(图论专项练习)

A题: 网络流最大流模型. 用 [1, m] 表示各个国家,[m+1, m+n] 表示各个餐桌. 从 s 向 i 连边,容量为第 i 个国家的代表数: 从 m+i 向 t 连边,容量为第 i 张餐桌的容量: 从 i 向 j + m 连边,容量为 1 ,这样就限制了每个国家在一个餐桌上至多有一个代表. 找到最大流,表示满足条件的代表数量最大值,再与提前计算出的代表总数量比较, 两者如果相等说明存在合理方案,输出 1 ,否则输出 0. B题: 二分图的最大匹配模型. 我在比赛的时候考虑了费用流,在"

2015山东毕业生如何进行网上报道(报到证)?

这两天 一直很头疼,报道证的问题,毕了业也是很蛋疼的问题.我真的不知道该怎么办,网络上都的都是一些垃圾.根不知 所云为何物? 然后自己摸索. 解决方案: 1 打电话问一下 比 报到证上面的 人事保障局的电话.咨询一下是否可以网上办理? 2 可以话,您可以接着往下看了. 如果不行,您只能去当地办理.这个我也没有经验呀. 你打电话问一下. 3 网址:山东省高校毕业生就业信息网 记住只能用IE打开亲! http://www.sdbys.cn/index.html 4 注册我就不说了,你自己看着办吧,还

2014年山东省信息学奥林匹克夏令营资料

本次山东省信息学夏令营的一些资料: 文件: 2014山东夏令营基础二.7z大小: 6777145 字节MD5: B6046D8844DF229C5D0D8D974DB35030SHA1: D580E17663DF38C48DD663BC6853CA5F09E83AD5CRC32: 07CA13FE 文件:2014山东夏令营提高一.7z大小: 25817580 字节MD5: 3CE876F151539C122E6AAC55A17083E5SHA1: 62064EA65A6285A018B9C869

[GRYZ]寒假模拟赛

写在前面 这是首次广饶一中的OIERS自编自导,自出自做(zuo)的模拟赛. 鉴于水平气压比较低,机(wei)智(suo)的WMY/XYD/HYXZC就上网FQ下海找了不少水(fei)题,经过他们优(le)美(se)的文字加工后,有故事有题目有人物有奸情的模拟赛正式呈上. 我是正文 题目名 GRYZ娱乐时刻 GRYZ追击时刻 GRYZ就餐时刻 源文件 hyxzc.cpp/c/pas clikar.cpp/c/pas eat.cpp/c/pas 输入文件 hyxzc.in clikar.in ea

跑跑卡丁车单机版商品代码

注:此商品代码仅供参考或本地体验之用,如有侵权请邮件通知. 更新信息(不定期更新):商品代码已更新至[路战舰9][泰坦9][鲨鱼船长9] 小提示:可以使用浏览器的搜索功能来快速定位道具名称的位置. 1 = 皮蛋(金币)2 = 黑妞(金币)3 = 蓝色喷漆(金币)4 = 绿色喷漆(金币)5 = 青绿色喷漆(金币)6 = 紫色喷漆(金币)7 = 蓝色星星(金币)8 = 黄色星星(金币)9 = 绿色星星(金币)10 = 爆烈 C1(30天)11 = 合金 C1(30天)12 = 尖锋 C1(30天)1

山西矿山破碎机除尘器的组成特点

山西矿山破碎机除尘器介绍 山西矿山破碎机除尘器专业生产厂家针对各种采石场.破碎.筛选石料厂的烟尘治理与粉尘收集特点提供破碎机除尘器报价.制造.使用方案. 山西破碎机除尘器也称矿山破碎机除尘器用在矿厂破碎系统中,处置矿石在被机器破碎.分别.运送过程中,扬尘过大污染严重问题,破碎机除尘器在扬尘点设备吸尘设备,把扬尘通过负压吸入破碎机除尘器箱体进行净化处置,把扬尘中的粉尘与洁净空气进行分别. 山西矿山破碎机除尘器的组成 山西破碎机除尘器首要是采用上.下箱体.灰斗.排灰设备.过滤设备.喷吹设备.引风机等

对美网攻击事件负责 中企如何回应

10月21日,美国多个城市出现互联网瘫痪情况,包括Twitter.Shopify.Reddit等在内的大量互联网知名网站数小时无法正常访问.为众多网站提供域名解析服务的美国Dyn公司称,公司遭到大规模的"拒绝访问服务"(DDoS)攻击. 安全研究人员的话说,被称作Mirai的恶意文件,一直在利用"雄迈"产品中的缺陷,在注入恶意代码,并利用它们发动大规模分布式拒绝服务攻击. 即便瘫痪事件的元凶尚未查明,但美国网站KerbsonSecurity认为"雄迈科技&