Description

Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查。他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T。这些城镇之间通过R条道路 (1 <= R <= 50,000,编号为1到R) 和P条航线 (1 <= P <= 50,000,编号为1到P) 连接。每条道路i或者航线i连接城镇A_i (1 <= A_i <= T)到B_i (1 <= B_i <= T),花费为C_i。对于道路,0 <= C_i <= 10,000;然而航线的花费很神奇,花费C_i可能是负数(-10,000 <= C_i <= 10,000)。道路是双向的,可以从A_i到B_i,也可以从B_i到A_i,花费都是C_i。然而航线与之不同,只可以从A_i到B_i。事实上,由于最近恐怖主义太嚣张,为了社会和谐,出台 了一些政策保证:如果有一条航线可以从A_i到B_i,那么保证不可能通过一些道路和航线从B_i回到A_i。由于FJ的奶牛世界公认十分给力,他需要运送奶牛到每一个城镇。他想找到从发送中心城镇S(1 <= S <= T) 把奶牛送到每个城镇的最便宜的方案,或者知道这是不可能的。

Input

* 第1行:四个空格隔开的整数: T, R, P, and S * 第2到R+1行:三个空格隔开的整数(表示一条道路):A_i, B_i 和 C_i * 第R+2到R+P+1行:三个空格隔开的整数(表示一条航线):A_i, B_i 和 C_i

Output

* 第1到T行:从S到达城镇i的最小花费,如果不存在输出"NO PATH"。

Sample Input

6 3 3 4

1 2 5

3 4 5

5 6 10

3 5 -100

4 6 -100

1 3 -10

样例输入解释:

一共六个城镇。在1-2,3-4,5-6之间有道路,花费分别是5,5,10。同时有三条航线:3->5,

4->6和1->3,花费分别是-100,-100,-10。FJ的中心城镇在城镇4。

Sample Output

NO PATH

NO PATH

5

0

-95

-100

样例输出解释:

FJ的奶牛从4号城镇开始,可以通过道路到达3号城镇。然后他们会通过航线达到5和6号城镇。

但是不可能到达1和2号城镇。

 
 
思路:
因为有负权边,所以不能使用dijstra,但是这个数据量使用spfa会t,所以我们考录heap+dijstra。
如何解决负权边呢??注意题目:如果有一条航线可以从A_i到B_i,那么保证不可能通过一些道路和航线从B_i回到A_i。
这就说明,单向边一定不会形成环。
所以一个联通块中,不可能有一个起点和终点都在这个强联通块的单向边,然且对于两个强连通块,只能出项从一个块指向另一个块的单向边,若相互指向,则会形成环
那么对于一个联通块,我们可以只考虑双向边,直接使用dijstra,然后对从这个联通块发出的单向边进行更新,更新其他联通块中的dist,然后把处理过的单向边抹去。
 
因为是从s到其他点的距离,所以如果从一个联通块,没有单向边指向它,并且还不是s所在联通块,那么它里面的点都是无法到达的(显然)
 
 
①所以,我们可以按照拓扑序进行更新,每处理完一个联通块,和其单向边,我们就消除单向边造成的入度,然后进行拓扑排序选择联通块。
这样写法s所在联通块并不一定第一个入队,但是其前入队的联通块最短路无法更新,只能消除单向边,写法清晰。
 
②我们也一开始可以就把s的联通块号传入,这样的话,其他入度为0的联通块指出的单向边,我们直接需要将其抹去,消除无效联通块对其他联通快造成的入度。
因为其他入度为0的联通块,是无效的。(代码注释部分)
 
 
 #include<bits/stdc++.h>
using namespace std; int t,r,p,s;
typedef pair<int,int> pii;
const int maxn = 5e4+;
vector<int>belong[maxn];
struct Node
{
int x,y,val,next;
Node(int x=,int y=,int val=,int next=):x(x),y(y),val(val),next(next) {}
} node[][maxn<<]; int head[][maxn];
int cnt[];
int tot;
void add(int x,int y,int val,int t)
{
node[t][++cnt[t]].x = x;
node[t][cnt[t]].y = y;
node[t][cnt[t]].val = val;
node[t][cnt[t]].next = head[t][x];
head[t][x] = cnt[t];
}
int cn[maxn];
int ind[maxn];
int dist[maxn];
bool vis[maxn];
void dfs(int x)
{
cn[x] = tot;
belong[tot].push_back(x);
for(int i=head[][x]; i; i=node[][i].next)
{
int y = node[][i].y;
if(cn[y])
continue;
dfs(y);
}
}
void solve(int s)
{
queue<int>que;
while(!que.empty())
que.pop();
for(int i=; i<=tot; i++)
if(!ind[i])
que.push(i);
// for(int i=1; i<=tot; i++)
// {
// if(!ind[i] && i != cn[s])
// {
// for(int j=0; j<belong[i].size(); j++)
// {
// for(int k=head[1][belong[i][j]]; k; k=node[1][k].next)
// {
// --ind[cn[node[1][k].y]];
// }
// }
// ind[i] = -1;
// //printf("%d ------ %d\n",ind[i],i);
// i=0;
// }
// }
// que.push(cn[s]);
memset(dist,0x3f,sizeof(dist));
dist[s] = ;
priority_queue<pii,vector<pii>,greater<pii> >p;
while(!que.empty())
{
int k = que.front();
que.pop();
while(!p.empty())
p.pop();
int len = belong[k].size();
for(int i=; i<len; i++)
{
if(dist[belong[k][i]] < 0x3f3f3f3f)
p.push(pii(dist[belong[k][i]],belong[k][i]));
}
while(!p.empty())
{
pii t = p.top();
p.pop();
if(vis[t.second])
continue;
vis[t.second] = ;
for(int i=head[][t.second]; i; i=node[][i].next)
{
if(dist[t.second] + node[][i].val < dist[node[][i].y])
{
dist[node[][i].y] = dist[t.second] + node[][i].val;
p.push(pii(dist[t.second] + node[][i].val,node[][i].y));
}
}
for(int i=head[][t.second]; i; i=node[][i].next)
{
dist[node[][i].y] = min(dist[node[][i].y],dist[t.second]+node[][i].val);
}
}
for(int i=; i<len; i++)
{
for(int j=head[][belong[k][i]]; j; j=node[][j].next)
{
if(--ind[cn[node[][j].y]] == )
que.push(cn[node[][j].y]);
}
}
}
} int main()
{
cnt[] = cnt[] = ;
scanf("%d%d%d%d",&t,&r,&p,&s);
for(int i=; i<=t; i++)
belong[i].clear();
for(int i=; i<=r; i++)
{
int u,v,k;
scanf("%d%d%d",&u,&v,&k);
add(u,v,k,);
add(v,u,k,);
} for(int i=; i<=p; i++)
{
int u,v,k;
scanf("%d%d%d",&u,&v,&k);
add(u,v,k,);
}
tot = ;
for(int i=; i<=t; i++)
{
if(!cn[i])
{
tot++;
dfs(i);
}
} for(int i=; i<=cnt[]; i++)
{
ind[cn[node[][i].y]]++;
}
solve(s);
for(int i=; i<=t; i++)
{
if(dist[i] == 0x3f3f3f3f)
printf("NO PATH\n");
else
printf("%d\n",dist[i]);
}
}
 

2200: [Usaco2011 Jan]道路和航线 (拓扑排序+dijstra)的更多相关文章

  1. bzoj 2200: [Usaco2011 Jan]道路和航线——拓扑+dijkstra

    Description Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条 ...

  2. BZOJ 2200: [Usaco2011 Jan]道路和航线

    Description Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条 ...

  3. [BZOJ 2200][Usaco2011 Jan]道路和航线 spfa+SLF优化

    Description Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条 ...

  4. 【BZOJ】2200: [Usaco2011 Jan]道路和航线

    [题意]给定n个点的图,正权无向边,正负权有向边,保证对有向边(u,v),v无法到达u,求起点出发到达所有点的最短距离. [算法]拓扑排序+dijkstra [题解]因为有负权边,直接对原图进行spf ...

  5. bzoj 2200: [Usaco2011 Jan]道路和航线【spfa】

    直接跑最短路就行了--还不用判负环 #include<iostream> #include<cstdio> #include<queue> using namesp ...

  6. bzoj2200: [Usaco2011 Jan]道路和航线

    先忽略航线,求出图中所有连通块,再用航线拓扑排序求出每个连通块的优先级 然后dijkstra时优先处理优先级高的块里的点就行了 ps:这题SPFA会TLE #include <iostream& ...

  7. [Usaco2011 Jan]道路和航线

    Description Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条 ...

  8. BZOJ 2200--[Usaco2011 Jan]道路和航线(最短路&拓扑排序)

    2200: [Usaco2011 Jan]道路和航线 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1128  Solved: 414[Submit] ...

  9. BZOJ2200 道路和航线【好题】【dfs】【最短路】【缩点】

    2200: [Usaco2011 Jan]道路和航线 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1384  Solved: 508[Submit] ...

随机推荐

  1. swift 实践- 05 -- UITextField

    import UIKit class ViewController: UIViewController ,UITextFieldDelegate{ // 文本框的创建, 有如下几个样式: // UIT ...

  2. 信息摘要算法之七:SHA在区块链中的应用

    最近几年比特币的火爆带动了人们对区块链技术的研究.当然我们在这里并不讨论区块链技术本身,而是讨论一下区块链中的SHA算法的应用.对于SHA系列算法我们已经在前面作了说明,在这里也不再重复. 1.区块链 ...

  3. Confluence 6 Oracle 创建数据库用户

    创建用户后并且指派权限: 使用 sqlplus 命令行工具通过命令行来访问 Oracle sqlplus user/password <as sysdba|as sysoper> 如果你的 ...

  4. iframe与主框架跨域相互访问方法

    iframe 与主框架相互访问方法  http://blog.csdn.net/fdipzone/article/details/17619673/ 1.同域相互访问 假设A.html 与 b.htm ...

  5. 好用的JS拖拽插件

    下载artDialog插件的时候发现它把拖拽单独封装成了一个方法,挺好用的,使用方法如下... 第一种拖拽方式-点击容器指定区域进行拖拽 $('.ui-dialog').on(DragEvent.ty ...

  6. jquery----Ajax补充

    jquery实现ajax请求 <script> //$.ajax的两种使用方式: //$.ajax(settings); //$.ajax(url,[settings]); $(" ...

  7. 十图详解tensorflow数据读取机制(附代码)转知乎

    十图详解tensorflow数据读取机制(附代码) - 何之源的文章 - 知乎 https://zhuanlan.zhihu.com/p/27238630

  8. ActiveSync 学习记录

    协议就是一种规范.它是高效团队协作的依据.有的人可能不爱看团队规范之类的文档,一方面是个人意识问题,另外也和文档的组织.协作的效果相关. 写好文档: 看好文档. 1. 处理XML转码 抓包后,发现邮件 ...

  9. 一条bash命令,清除指定的网络接口列表

    在K8S的安装配置过程, 由于不断的测试, 会不断的生成各式各样的虚拟网络接口. 那么,不重新安装之前,清除前次产生的这些垃圾接口, 不让它们影响下次的测试,是很有必要的. 如何快速删除呢? 如下命令 ...

  10. Top 查看某些或者某个进程(top -p pid)

    https://blog.csdn.net/zhangfn2011/article/details/7488746?utm_source=blogxgwz5