题意:

给定一个有向图,求从源点到其他各点的往返最短路径和。且这个图有一个性质:任何一个环都会经过源点。

图中的节点个数范围:0~100w;

分析:

我们先可以利用Dijkstra算法求解从源点到其余各点的最短距离,这样工作就完成了一半了。

那么如何求解从各点到源点的最短路呢?

1. 我们可以循环n-1次,每次计算点i到其余各点的最短路,从中取出i到源点的最短路,这样我们就可以其余各点到源点的最短路。

显然上述方法中存在大量冗余,显然针对题目的取值范围:0~100w,必定会超时的。如果你不信,可以试试。

按照上诉方法实践,超时的代码:

#include<cstdio>
#include<string.h>
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
#define maxn 1000000
#define inf 0x3f3f3f3f
typedef pair<int,int> P;
struct edge{
int t;
int c;
edge(){ t=0,c=0;}
edge(int tt,int cc){
t=tt,c=cc;
}
};
int dist[maxn];
vector<edge> map[maxn];
void dijkstra(int s,int n){
priority_queue<P,vector<P>,greater<P> > Q;
for(int i=1;i<=n;i++)
dist[i]=inf;
dist[s]=0;
bool visited[maxn];
memset(visited ,0,sizeof(visited)); Q.push(P(0,s));
while(!Q.empty()){
int v=Q.top().second;
Q.pop();
if(visited[v]) continue;
visited[v]=true;
for(int i=0;i<map[v].size();i++){
edge e=map[v][i];
if(dist[e.t]>dist[v]+e.c){
dist[e.t]=dist[v]+e.c;
Q.push(P(dist[e.t],e.t));
}
}
}
}
void init(int n){
for(int i=0;i<=n;i++){
map[i].clear();
}
}
int main(){
//freopen("in.txt","r",stdin);
int cases;
scanf("%d",&cases);
for(int t=1;t<=cases;t++){
int n,m;
scanf("%d %d",&n,&m);
init(n);
while(m--){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
map[a].push_back(edge(b,c));
}
dijkstra(1,n);
int sum=0;
for(int i=1;i<=n;i++)
sum+=dist[i];
for(int i=2;i<=n;i++){
dijkstra(i,n);
sum+=dist[1];
}
printf("%d\n",sum);
}
}

2.经过别人题解指点,发现一个很好的方法。

首先,我们需要构造原图的反图。

原图为有向图,反图为建立在原图的基础之上,原图的边的源点为反图的终点,原图的边的终点为反图的源点。

总之,把原图的边的方向全部反转,就构成了反图。

在构建完反图后,我们再来对反图应用Dijkstra算法,源点为1.

接着,我们获得了从源点到其余各点的最短距离,注意我们的图是原图的反图,所以:

我们获得的其实是其余各点到源点的最短距离。

3.邻接表还是二维矩阵?

我们还需注意一个重要的问题:如何存储边信息?

按照题目中的数据范围0-100w,我们是无法开辟那么大的二维矩阵的,所以我们必须利用邻接表存储。

在这里我们使用vector实现。

源代码:

#include<cstdio>
#include<string.h>
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
#define maxn 1000001
#define inf 0x3f3f3f3f
typedef pair<int,int> P;
struct edge{
int f;
int t;
int c;
edge(){ f=0,t=0,c=0;}
edge(int ff,int tt,int cc){
f=ff,t=tt,c=cc;
}
};
int dist[maxn];
vector<edge> map[maxn];
edge edges[maxn];
void dijkstra(int s,int n){
priority_queue<P,vector<P>,greater<P> > Q;
for(int i=1;i<=n;i++)
dist[i]=inf;
dist[s]=0;
bool visited[maxn];
memset(visited ,0,sizeof(visited)); Q.push(P(0,s));
while(!Q.empty()){
int v=Q.top().second;
Q.pop();
if(visited[v]) continue;
visited[v]=true;
for(int i=0;i<map[v].size();i++){
edge e=map[v][i];
if(dist[e.t]>dist[v]+e.c){
dist[e.t]=dist[v]+e.c;
Q.push(P(dist[e.t],e.t));
}
}
}
}
void init(int n){
for(int i=0;i<=n;i++){
map[i].clear();
}
}
int main(){
//freopen("in.txt","r",stdin);
int cases;
scanf("%d",&cases);
for(int t=1;t<=cases;t++){
int n,m;
scanf("%d %d",&n,&m);
init(n);
for(int i=1;i<=m;i++){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
edges[i]=edge(a,b,c);
map[a].push_back(edge(a,b,c));
}
dijkstra(1,n);
long long int sum=0;
for(int i=1;i<=n;i++)
sum+=dist[i];
init(n);
for(int i=1;i<=m;i++){
edge tmp=edges[i];
map[tmp.t].push_back(edge(tmp.t,tmp.f,tmp.c));
}
dijkstra(1,n);
for(int i=1;i<=n;i++)
sum+=dist[i];
printf("%lld\n",sum);
}
}

POJ - 1511 Invitation Cards(Dijkstra变形题)的更多相关文章

  1. POJ 1511 - Invitation Cards (dijkstra优先队列)

    题目链接:http://poj.org/problem?id=1511 就是求从起点到其他点的最短距离加上其他点到起点的最短距离的和 , 注意路是单向的. 因为点和边很多, 所以用dijkstra优先 ...

  2. POJ 1511 Invitation Cards(Dijkstra(优先队列)+SPFA(邻接表优化))

    题目链接:http://poj.org/problem?id=1511 题目大意:给你n个点,m条边(1<=n<=m<=1e6),每条边长度不超过1e9.问你从起点到各个点以及从各个 ...

  3. 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 / ...

  4. POJ 1511 Invitation Cards(单源最短路,优先队列优化的Dijkstra)

    Invitation Cards Time Limit: 8000MS   Memory Limit: 262144K Total Submissions: 16178   Accepted: 526 ...

  5. DIjkstra(反向边) POJ 3268 Silver Cow Party || POJ 1511 Invitation Cards

    题目传送门 1 2 题意:有向图,所有点先走到x点,在从x点返回,问其中最大的某点最短路程 分析:对图正反都跑一次最短路,开两个数组记录x到其余点的距离,这样就能求出来的最短路以及回去的最短路. PO ...

  6. poj 1511 Invitation Cards(最短路中等题)

    In the age of television, not many people attend theater performances. Antique Comedians of Malidine ...

  7. [POJ] 1511 Invitation Cards

    Invitation Cards Time Limit: 8000MS   Memory Limit: 262144K Total Submissions: 18198   Accepted: 596 ...

  8. POJ 1511 Invitation Cards (最短路spfa)

    Invitation Cards 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/J Description In the age ...

  9. SPFA算法(2) POJ 1511 Invitation Cards

    原题: Invitation Cards Time Limit: 8000MS   Memory Limit: 262144K Total Submissions: 31230   Accepted: ...

  10. poj 1511 Invitation Cards (最短路)

    Invitation Cards Time Limit: 8000MS   Memory Limit: 262144K Total Submissions: 33435   Accepted: 111 ...

随机推荐

  1. 重建中国.NET生态系统

    Neuzilla官方微信公众号:搜 架构师联盟 或 neuzilla 我是.NET铁杆粉丝,所以如果你要在评论里跟我撕逼.NET怎么怎么烂,Java.C++.PHP.JavaScript怎么怎么好,我 ...

  2. Loom工具类:Unity3D巧妙处理多线程

    Loom代码不多,只有168行, 然而却具备了子线程运行Action, 子线程与主线程交互的能力! public static Thread RunAsync(Action a) public sta ...

  3. NHibernate无法将类型“System.Collections.Generic.IList<T>”隐式转换为“System.Collections.Generic.IList<IT>

    API有一个需要实现的抽象方法: public IList<IPermission> GetPermissions(); 需要注意的是IList<IPermission>这个泛 ...

  4. nios II--实验1——hello_world软件部分

    hello_world 软件开发 首先,在硬件工程文件夹里面新建一个software的文件夹用于放置软件部分:打开toolsàNios II 11.0 Software Build Tools for ...

  5. 51单片机中断interrupt……using……

    51单片机中断细节的一些问题. interrupt0:外部中断0interrupt1:定时器中断0interrupt2:外部中断interrupt3:定时器中断1interrupt4:串口 using ...

  6. matlab 画图数据导入

    http://www.yiibai.com/matlab/matlab_data_import.html Python 执行py 文件: 在要执行文件处按shift右击鼠标打开cmd 命令窗口,输入: ...

  7. social emotion computing-感情的分类

    第八节  情感的分类 人的情感复杂多样,可以从不同的观察角度进行分类.由于情感的核心内容是价值,因此人的情感主要必须根据它所反映的价值关系的运动与变化的不同特点来进行分类. 1.根据价值的正负变化方向 ...

  8. 部署到IIS上的网站打开时总是显示无法找到资源解决方案

    1.首先修改项目目录的访问权限:右键->属性->安全里面找到组名或用户名 ->编辑->添加一个用户取名everyOne并设置可以修改即可 2.然后在IIS下面,选中你的mvc项 ...

  9. linux下PHP7环境搭建

    LAMP环境版本 操作系统:Centos 7 Mysql:5.7.11 Apache:2.4.18 PHP:7.0.4     安装Mysql   下载链接:http://dev.mysql.com/ ...

  10. android-之测试框架的使用AndroidTestCase

    Android Manifest.xml中所需要添加的配置 <instrumentation android:name="android.test.InstrumentationTes ...