题意:给出一张有向图,每条边有长度,对于每条边,你要回答将该边的方向取反后,从起点到终点的最短距离是增加or减小or不变。

首先求出起点到所有点的最短距离和所有点到终点的最短距离(两次DIjkstra,第二次跑反向边即可),并建出最短路图。设ds[u]为起点到点u的最短距离,dt[u]为点u到终点的最短距离,对于每条边,设该边的两个端点u->v,以及边权c,分情况讨论:

若ds[v]+c+dt[u]>dt[s],此时将边取反后最短距离减小,否则需要判断该边是否为最短路图上s到t的割边,若是则最短距离增加,否则不变。

如何判断该边是否为s到t的割边?其实方法很简单,如果是割边,那么从s到t的所有路径都经过该边。由于最短路图是个DAG,设in[u]表示从起点走到u的路径数,out[v]表示从v走到终点的路径数,则每条边被通过的路径数=in[u]*out[v],只需判断in[u]*out[v]是否等于out[s]即可。注意这个路径数可能会很大甚至存不下,但由于只需要判断是否相等用哈希就可以,可以用unsigned long long溢出自动取模。

 #include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int N=1e5+,inf=0x3f3f3f3f;
int n,m,hd[N],ne;
ll in[N],out[N],ds[N],dt[N],vis[N];
struct E {int u,v,c,nxt;} e[N<<];
void addedge(int u,int v,int c) {e[ne]= {u,v,c,hd[u]},hd[u]=ne++;}
struct D {
int u;
ll g;
bool operator<(const D& b)const {return g>b.g;}
};
priority_queue<D> q;
void upd(int u,ll ad,ll* dp) {
if(dp[u]>ad)dp[u]=ad,q.push({u,ad});
}
void dij() {
memset(ds,inf,sizeof ds);
while(q.size())q.pop();
upd(,,ds);
while(q.size()) {
int u=q.top().u;
ll g=q.top().g;
q.pop();
if(ds[u]!=g)continue;
for(int i=hd[u]; ~i; i=e[i].nxt)if(!(i&))upd(e[i].v,g+e[i].c,ds);
}
memset(dt,inf,sizeof dt);
while(q.size())q.pop();
upd(,,dt);
while(q.size()) {
int u=q.top().u;
ll g=q.top().g;
q.pop();
if(dt[u]!=g)continue;
for(int i=hd[u]; ~i; i=e[i].nxt)if(i&)upd(e[i].v,g+e[i].c,dt);
}
}
ll dfsin(int u) {
ll& ret=in[u];
if(vis[u])return ret;
vis[u]=,ret=;
if(u==)return ret=;
for(int i=hd[u]; ~i; i=e[i].nxt)if(i&) {
int v=e[i].v;
if(dt[u]+e[i].c!=dt[v])continue;
ret+=dfsin(v);
}
return ret;
}
ll dfsout(int u) {
ll& ret=out[u];
if(vis[u])return ret;
vis[u]=,ret=;
if(u==)return ret=;
for(int i=hd[u]; ~i; i=e[i].nxt)if(!(i&)) {
int v=e[i].v;
if(ds[u]+e[i].c!=ds[v])continue;
ret+=dfsout(v);
}
return ret;
}
int main() {
memset(hd,-,sizeof hd),ne=;
scanf("%d%d",&n,&m);
while(m--) {
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
addedge(u,v,c);
addedge(v,u,c);
}
dij();
memset(vis,,sizeof vis);
for(int i=; i<=n; ++i)dfsin(i);
memset(vis,,sizeof vis);
for(int i=; i<=n; ++i)dfsout(i);
for(int i=; i<ne; i+=) {
int u=e[i].u,v=e[i].v;
if(dt[]>ds[v]+e[i].c+dt[u])puts("HAPPY");
else if(ds[u]+e[i].c==ds[v]&&in[u]*out[v]==out[])puts("SAD");
else puts("SOSO");
}
return ;
}

Aizu - 1383 Pizza Delivery (最短路图+DAG上的割边)的更多相关文章

  1. [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)

    [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...

  2. Vulnerable Kerbals CodeForces - 772C【拓展欧几里得建图+DAG上求最长路】

    根据拓展欧几里得对于同余方程 $ax+by=c$ ,有解的条件是 $(a,b)|c$. 那么对于构造的序列的数,前一个数 $a$  和后一个数 $b$ ,应该满足 $a*x=b(mod m)$ 即 $ ...

  3. Pizza Delivery

    Pizza Delivery 时间限制: 2 Sec  内存限制: 128 MB 题目描述 Alyssa is a college student, living in New Tsukuba Cit ...

  4. [NOIP2017]逛公园 最短路图 拓扑序DP

    ---题面--- 题解: 挺好的一道题. 首先我们将所有边反向,跑出n到每个点的最短路,然后f[i][j]表示从i号节点出发,路径长比最短路大j的方案数. 观察到,如果图中出现了0环,那么我们可以通过 ...

  5. 【暑假】[深入动态规划]UVa 1628 Pizza Delivery

    UVa 1628 Pizza Delivery 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=51189 思路:    ...

  6. [HAOI2012]道路(最短路DAG上计数)

    C国有n座城市,城市之间通过m条[b]单向[/b]道路连接.一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小.两条最短路不同,当且仅当它们包含的道路序列不同.我们需要对每 ...

  7. 【NOIP2017】逛公园(最短路图,拓扑排序,计数DP)

    题意: 策策同学特别喜欢逛公园. 公园可以看成一张 N 个点 M 条边构成的有向图,且没有自环和重边.其中 1 号点是公园的入口, N 号点是公园的出口,每条边有一个非负权值,代表策策经过这条边所要花 ...

  8. codeforces Gym 100338C Important Roads (重建最短路图)

    正反两次最短路用于判断边是不是最短路上的边,把最短路径上的边取出来建图.然后求割边.注意重边,和卡spfa. 正权,好好的dijkstra不用,用什么spfa? #include<bits/st ...

  9. Codeforces Round #545 (Div. 2) E 强连通块 + dag上求最大路径 + 将状态看成点建图

    https://codeforces.com/contest/1138/problem/E 题意 有n个城市(1e5),有m条单向边(1e5),每一周有d天(50),对于每个城市假如在某一天为1表示这 ...

随机推荐

  1. 字符编码笔记:ASCII,Unicode 和 UTF-8(理解)

    1.ASCII 码 美国制定的字符编码规则,对英语字符与二进制位之间的关系做了统一规定. 占一个字节,8 位,最多可表示 2^8 = 256 种状态(字符) 实际共有 128 个字符,只占用一个字节的 ...

  2. Linux Crontab格式说明

    Crontab基本格式: * * * * * command 分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用 */1表示 第2列表示小时1-23(0表示0点) 第3列表示日期1-31 第4 ...

  3. centos7 虚拟机 A start job is running for /etc/rc.d/rc.local Comp。。。

    一直卡这F5查看日志,最后一行出现A start job is running for /etc/rc.d/rc.local Comp... 原因是rc.local权限设错了解决方法:1.进入单用户模 ...

  4. 记一次INFA抽取数据报 WRT_8165 - TIMEOUT_BASED_COMMIT_POINT错误

    今天抽取数据报1千多W的数据报错 powercenter workflow卡死不动,也没报错就显示 timeout based commit point  WRT_8165 - TIMEOUT_BAS ...

  5. ACM-ICPC 2018 徐州赛区网络预赛 I. query 树状数组

    I. query 题目链接: Problem Description Given a permutation \(p\) of length \(n\), you are asked to answe ...

  6. Java:main方法前面一定要加static?在main方法中一定要调用static方法?

    今天敲代码的时候发现,出现了这样一个情况: 我在我在main方法中调用了一个函数,并且这个函数没有用static修饰,就像这样: 这样报错了!!! 我虽然学Java 的时间也不多,但这个问题也帮助我更 ...

  7. 题解 CF546C 【Soldier and Cards】

    思路 是一道水题,可以用队列+模拟来写,注意不要拿完队列中的元素! 代码 #include<iostream> #include<cstdio> #include<que ...

  8. 宝塔面板liunx开启ssl域名后无法访问解决方法

    不打开宝塔面板的ssl会不安全,打开了就会提示ssl证书不能使用的错误 如下所示: 您的连接不是私密连接 攻击者可能会试图从 你的ip 窃取您的信息(例如:密码.通讯内容或信用卡信息).了解详情 NE ...

  9. 计算机网络(TCP/IP)

    概述:网络协议通常分不同的层次进行开发,每一层分别不同的通信功能.TCP/IP通常分为4层协议系统. 1.链路层,有时也称为数据链路层或者网络接口层,通常包括操作系统中的设备驱动程序和计算机中对应的网 ...

  10. 怎样获取不同环境下的document对象

    1. 在一般的网页文档中, 可通过: document 或 window.document 获取; 2. 在iframe框架中, 可通过iframe节点的属性: contentDocument 获取; ...