POJ-1511 Invitation Cards (单源最短路+逆向)
<题目链接>
题目大意:
有向图,求从起点1到每个点的最短路然后再回到起点1的最短路之和。
解题分析:
在求每个点到1点的最短路径时,如果仅仅只是遍历每个点,对它们每一个都进行一次最短路算法,那么即使是用了堆优化的dijkstra,时间复杂度也高达$O(n^2log(n))$,而本题有1000000个点,毫无疑问,这种想法必然是不可行的,所以我们可以采用逆向思维,将图中的每一条有向边全部反向,然后以1为起点,仅做一次dijkstra,就能得到1到所有点的最短距离,即反向前的,所有点到1点的最短距离。所以,本题的正解应为:先以1为起点,做一次dijkstra,算出,1到所有点的最短距离,然后将边反向,再以1为起点,做一次dijkstra,此时就能得到,其他所有点到1的最短距离,将所有的最短距离相加,即为答案。时间复杂度为$O(nlogn)$。
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std; #define INF 0x3f3f3f3f
const int maxn =+; int n,m;
struct Edge{
int to;
int next;
int w;
}; Edge edge[maxn],redge[maxn]; struct NODE{
int index;
int dis;
bool operator < (NODE const &tmp)const{
return dis>tmp.dis;
}
}d[maxn]; int dist[maxn];
int cnt,rcnt,head1[maxn],head2[maxn],vis[maxn]; void init(){
memset(head1,-,sizeof(head1));
memset(head2,-,sizeof(head2));
cnt=,rcnt=;
} void add1(int u,int v,int w){
edge[cnt].to=v;edge[cnt].w=w;
edge[cnt].next=head1[u];
head1[u]=cnt++;
} void add2(int u,int v,int w){
redge[rcnt].to=v;redge[rcnt].w=w;
redge[rcnt].next=head2[u];
head2[u]=rcnt++;
} void dijkstra1(int st){
for(int i=;i<=n;i++){
vis[i]=;d[i].dis=INF,d[i].index=i;
} priority_queue<NODE>q;
d[st].dis=;q.push(d[st]);
while(!q.empty()){
int u=q.top().index;
q.pop();
if(vis[u])continue;
vis[u]=;
for(int i=head1[u];i!=-;i=edge[i].next){
int v=edge[i].to;
if(d[v].dis>d[u].dis+edge[i].w){
d[v].dis=d[u].dis+edge[i].w;
q.push(d[v]);
}
}
}
} void dijkstra2(int st){ //因为正、反向边的edge[],和head[]散组不同,所以要将另外再写一个dijkstra函数
for(int i=;i<=n;i++){
vis[i]=;d[i].dis=INF,d[i].index=i;
} priority_queue<NODE>q;
d[st].dis=;q.push(d[st]);
while(!q.empty()){
int u=q.top().index;
q.pop();
if(vis[u])continue;
vis[u]=;
for(int i=head2[u];i!=-;i=redge[i].next){
int v=redge[i].to;
if(d[v].dis>d[u].dis+redge[i].w){
d[v].dis=d[u].dis+redge[i].w;
q.push(d[v]);
}
}
}
} int main(){
int t;scanf("%d",&t);
while(t--){
scanf("%d %d",&n,&m);
init();
for(int i=;i<=m;i++){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
add1(a,b,c); //存储该有向图正确的边
add2(b,a,c); //将该有向图的所有边反向存储
} long long sum=; dijkstra1(); //边未反向之前,求出1到所有点的最短路
for(int i=;i<=n;i++){
sum+=d[i].dis;
} dijkstra2(); //将边反向后,求出所有点到1点的最短路
for(int i=;i<=n;i++){
sum+=d[i].dis;
}
printf("%lld\n",sum);
}
return ;
}
2018-08-27
POJ-1511 Invitation Cards (单源最短路+逆向)的更多相关文章
- Invitation Cards POJ - 1511 (双向单源最短路)
In the age of television, not many people attend theater performances. Antique Comedians of Malidine ...
- POJ 1511 Invitation Cards / UVA 721 Invitation Cards / SPOJ Invitation / UVAlive Invitation Cards / SCU 1132 Invitation Cards / ZOJ 2008 Invitation Cards / HDU 1535 (图论,最短路径)
POJ 1511 Invitation Cards / UVA 721 Invitation Cards / SPOJ Invitation / UVAlive Invitation Cards / ...
- poj 1511 Invitation Cards (最短路)
Invitation Cards Time Limit: 8000MS Memory Limit: 262144K Total Submissions: 33435 Accepted: 111 ...
- POJ 1511 Invitation Cards(单源最短路,优先队列优化的Dijkstra)
Invitation Cards Time Limit: 8000MS Memory Limit: 262144K Total Submissions: 16178 Accepted: 526 ...
- poj 1511 Invitation Cards(最短路中等题)
In the age of television, not many people attend theater performances. Antique Comedians of Malidine ...
- POJ 1511 Invitation Cards (最短路spfa)
Invitation Cards 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/J Description In the age ...
- [POJ] 1511 Invitation Cards
Invitation Cards Time Limit: 8000MS Memory Limit: 262144K Total Submissions: 18198 Accepted: 596 ...
- DIjkstra(反向边) POJ 3268 Silver Cow Party || POJ 1511 Invitation Cards
题目传送门 1 2 题意:有向图,所有点先走到x点,在从x点返回,问其中最大的某点最短路程 分析:对图正反都跑一次最短路,开两个数组记录x到其余点的距离,这样就能求出来的最短路以及回去的最短路. PO ...
- POJ 1511 Invitation Cards (spfa的邻接表)
Invitation Cards Time Limit : 16000/8000ms (Java/Other) Memory Limit : 524288/262144K (Java/Other) ...
- Poj 1511 Invitation Cards(spfa)
Invitation Cards Time Limit: 8000MS Memory Limit: 262144K Total Submissions: 24460 Accepted: 8091 De ...
随机推荐
- POJ1679 The Unique MST【次小生成树】
题意: 判断最小生成树是否唯一. 思路: 首先求出最小生成树,记录现在这个最小生成树上所有的边,然后通过取消其中一条边,找到这两点上其他的边形成一棵新的生成树,求其权值,通过枚举所有可能,通过这些权值 ...
- springboot项目发布到独立的tomcat中运行&打成jar包运行
springboot的打包方式依赖于插件:(下面插件打出的包与普通的包目录结构有区别) <plugin> <groupId>org.springframework.boot&l ...
- HTTP协议中PUT和POST使用上的区别
有的观点认为,应该用POST来创建一个资源,用PUT来更新一个资源:有的观点认为,应该用PUT来创建一个资源,用POST来更新一个资源:还有的观点认为可以用PUT和POST中任何一个来做创建或者更新一 ...
- 【CTF MISC】隐写术wireshark找出图片-“强网杯”网络安全挑战赛writeup
这场CTF中有一道题是分析pcap包的.. 13.大黑阔: 从给的pcap包里把图片提取出来,是一张中国地图. 题目提示是黑阔在聊天,从数据里可以找出几段话. 思路:主要考察wireshark的过滤规 ...
- C语言练手游戏-控制台输出一个会移动的坦克
把C语言的知识融合起来做一个练手的小游戏项目,将自己掌握到的数据结构.数组.函数.宏定义等知识综合利用,增加对语法的熟练程度. 操作系统: windows 10 x64 编译IDE : VS2015 ...
- opencv入门指南(转载)
转载链接:http://blog.csdn.net/morewindows/article/details/8426318 网上的总结的一些用openncv的库来做的事: 下面列出OpenCV入门指南 ...
- [转]GDB-----1.GDB概述
作者: liigo原文链接: http://blog.csdn.net/liigo/archive/2006/01/17/582231.aspx 1.前言 本文写给主要工作在Windows操作系统下而 ...
- (DT系列五)Linux kernel 是怎么将 devicetree中的内容生成plateform_device【转】
转自:https://blog.csdn.net/lichengtongxiazai/article/details/38942033 Linux kernel 是怎么将 devicetree中的内容 ...
- Linux内存管理--物理内存分配【转】
转自:http://blog.csdn.net/myarrow/article/details/8682819 1. First Fit分配器 First Fit分配器是最基本的内存分配器,它使用bi ...
- linux系统的休眠与唤醒简介
转自:http://blog.csdn.net/haomcu/article/details/7398703 系统挂起(Suspend)是电源管理(APM&ACPI)的一个特性,给用户带来了很 ...