P1342 请柬

题目描述

在电视时代,没有多少人观看戏剧表演。Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片。他们已经打印请帖和所有必要的信息和计划。许多学生被雇来分发这些请柬。每个学生志愿者被指定一个确切的公共汽车站,他或她将留在那里一整天,邀请人们参与。

这里的公交系统是非常特殊的:所有的线路都是单向的,连接两个站点。公共汽车离开起始点,到达目的地之后又空车返回起始点。学生每天早上从总部出发,乘公交车到一个预定的站点邀请乘客。每个站点都被安排了一名学生。在一天结束的时候,所有的学生都回到总部。现在需要知道的是,学生所需的公交费用的总和最小是多少。

输入输出格式

输入格式:

第1行有两个整数n、m(1<=n,m<=1000000),n是站点的个数,m是线路的个数。

然后有m行,每行描述一个线路,包括3个整数,起始点,目的地和价格。

总部在第1个站点,价钱都是整数,且小于1000000000。

输出格式:

输出一行,表示最小费用。

输入输出样例

输入样例#1: 复制

4 6
1 2 10
2 1 60
1 3 20
3 4 10
2 4 5
4 1 50

输出样例#1: 复制

210 

说明

【注意】

此题数据规模较大,需要使用较为高效的算法,此题不设小规模数据分数。

基本模板题,spfa,正图(positive)和反图(negative)各搜一遍。

注意ans用long long。

AC代码如下:

#include<cstdio>
#include<algorithm>
#include<deque>
using namespace std;
const int N=1000000+5;
const int INF=1<<30;
struct p{
    int v,nxt,cost;
}po[N],neg[N];
int dis[N],po_fir[N],neg_fir[N],x,y,z,n,m,tot;
bool inq[N];
long long ans;
deque<int>q;
void add(int from,int to,int l)
{
    tot++;
    po[tot]=(p){to,po_fir[from],l};
    neg[tot]=(p){from,neg_fir[to],l};
    po_fir[from]=tot;
    neg_fir[to]=tot;
    return;
}
void po_spfa()
{
    q.push_back(1);
    fill(dis+2,dis+n+1,INF);
    dis[1]=0;
    while(!q.empty())
    {
        int now=q.front();
        q.pop_front();
        inq[now]=0;
        for(int i=po_fir[now];i;i=po[i].nxt)
        if(dis[po[i].v]>dis[now]+po[i].cost)
        {
            dis[po[i].v]=dis[now]+po[i].cost;
            if(!inq[po[i].v])
            {
                inq[po[i].v]=1;
                if(q.empty()||dis[q.front()]>dis[po[i].v]) q.push_front(po[i].v);
                else q.push_back(po[i].v);
            }
         }
    }
    for(int i=2;i<=n;i++)
    ans+=dis[i];
    return;
}
void neg_spfa()
{
    q.push_back(1);
    dis[1]=0;
    fill(dis+2,dis+n+1,INF);
    while(!q.empty())
    {
        int now=q.front();
        q.pop_front();
        inq[now]=0;
        for(int i=neg_fir[now];i;i=neg[i].nxt)
        if(dis[neg[i].v]>dis[now]+neg[i].cost)
        {
            dis[neg[i].v]=dis[now]+neg[i].cost;
            if(!inq[neg[i].v])
            {
                inq[neg[i].v]=1;
                if(q.empty()||dis[q.front()]>dis[neg[i].v]) q.push_front(neg[i].v);
                else q.push_back(neg[i].v);
            }
         }
    }
    for(int i=2;i<=n;i++)
    ans+=dis[i];
    return;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    scanf("%d%d%d",&x,&y,&z),add(x,y,z);
    po_spfa();
    neg_spfa();
    printf("%lld",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/Alex-leaves/p/8448014.html

时间: 2024-11-11 05:43:49

P1342 请柬的相关文章

洛谷 P1342 请柬

P1342 请柬 题目描述 在电视时代,没有多少人观看戏剧表演.Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片.他们已经打印请帖和所有必要的信息和计划.许多学生被雇来分发这些请柬.每个学生志愿者被指定一个确切的公共汽车站,他或她将留在那里一整天,邀请人们参与. 这里的公交系统是非常特殊的:所有的线路都是单向的,连接两个站点.公共汽车离开起始点,到达目的地之后又空车返回起始点.学生每天早上从总部出发,乘公交车到一个预定的站点邀请乘客.每个站点都被安排了一名

洛谷—— P1342 请柬

https://www.luogu.org/problemnew/show/1342 题目描述 在电视时代,没有多少人观看戏剧表演.Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片.他们已经打印请帖和所有必要的信息和计划.许多学生被雇来分发这些请柬.每个学生志愿者被指定一个确切的公共汽车站,他或她将留在那里一整天,邀请人们参与. 这里的公交系统是非常特殊的:所有的线路都是单向的,连接两个站点.公共汽车离开起始点,到达目的地之后又空车返回起始点.学生每天早上

[洛谷P1342]请柬

题目大意:有n个站,和m条单向边,每条边有乘车价值,保证汽车能开回来.有n-1个学生从1出发,分别到n-1个不同的点,然后回来.求最少的总价值. 解题思路:最短路,求回来的最少价值其实可以建立反向图,然后跑最短路即可.一共两遍最短路,我用堆优化Dijkstra算法,时间复杂度$O(m\log n)$. 注意long long. pbds大法好! C++ Code: #include<ext/pb_ds/priority_queue.hpp> #include<cstdio> #in

Luogu P1342 请柬 题解

差不多是Dijkstra的裸题吧... 这道题可以分为来回两个阶段. 去的时候很简单,直接用一次Dijkstra,然后统计答案. 回来的时候就有些巧妙了,虽然表面上是每个点回到起点,但是何尝不可将其看成从起点出发,逆着每个点过来的路去找一次每个点?所以只需要存边的时候处理一下,然后直接跑Dijkstra就行了. 附上代码. #include<bits/stdc++.h> #define clean(a,i) memset(a,i,sizeof(a)) #define ll long long

luogu P1342 请柬

dij板子的灵活运用 在一个有向图中求:1.1号点到剩下所有点的最短路 2.剩下所有点到一号点的最短路 1相信谁都会,存有向图跑一遍 2是这道题的精髓,应用一个比较有价值的思想:在有向图中跑反向边,相当于求出所有点到一号点的最短路 所以简单说就是存两个版本的图然后两遍dij板子 #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #include<queue>

P1342 请柬 建反图+dijkstra

题目链接 一句话题意:喊你求出从1出发到所有点的最短路以及所有点的最短路到1的最短路之和. 从1开始跑最短路很容易,直接一遍堆优化dijkstra就完了. 对于其他点到1的最短路又怎么求,不可能一个一个的求,所以想到之前暑假讲关于图论的技巧——建反图. 这样的话问题就迎刃而解了,再在反图上从1开始跑一遍最短路就完了. 代码如下: #include<bits/stdc++.h> using namespace std; const int maxn=2e6+7; const int inf=0x

春的请柬

既然眼睛已经长得很高 既然思绪已经染得很蓝 既然感情已经变得很暖 那就张开翅膀飞吧 飞出四季做的茧 既然嫌夏天太绿 既然嫌秋天太黄 既然嫌冬天太白 那就发一张请柬吧 ——邀请春天

BZOJ4277:萃香的请柬——题解

https://www.luogu.org/problemnew/show/P4277 萃香在小时候就一直有一个梦想,就是邀请全乡居民一起参加宴会,在上次发动异变被灵梦退治之后她仍旧没有放弃,而是在元宵节前早早准备好了难以计数的请柬. 现在,宴会即将开始,萃香却还是有一大堆请柬没有送出.经过大数学家琪露诺的严谨推算,到2018年时幻想乡的居民数目已经远远超过了外界,而这就使得宴会的邀请变得极为困难. 但是,拥有"操纵密度程度的能力"的萃香可以分成大大小小的萃香一起去送请柬.由于小萃香的

[洛谷1342]请柬

题目大意: 给定一个起点,求以其余所有点分别为必经点的最短回路之和. 思路: 建立反向图,在正反图上分别跑一遍Dijkstra,最后求和即可.注意数据规模,要开long long不然会WA,只能拿25分. 1 #include<cstdio> 2 #include<cctype> 3 #include<vector> 4 #include<ext/pb_ds/priority_queue.hpp> 5 inline int getint() { 6 regi