http://acm.hdu.edu.cn/showproblem.php?pid=3191

求次短路的长度和个数

相关分析在这里http://blog.csdn.net/u012774187/article/details/40681515

#pragma comment(linker, "/STACK:36777216")
#pragma GCC optimize ("O2")
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define clr0(x) memset(x,0,sizeof(x))
#define clr1(x) memset(x,-1,sizeof(x))
#define eps 1e-9
const double pi = acos(-1.0);
typedef long long LL;
typedef unsigned long long ULL;
const int modo = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int inf = 0x3fffffff;
const LL _inf = 1e18;
const int maxn = 55,maxm = 10005;
struct edge{
int v,w,next;
edge(){};
edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};
}e[maxn*maxn*2];
int head[maxn],inq[maxn][2],dist[maxn][2],cnt[maxn][2];//0最短1次短
int n,m,ecnt;
void init()
{
clr1(head);
ecnt = 0;
for(int i = 1;i <= maxn;++i)
dist[i][0] = dist[i][1] = inf;
//fill(dist,dist+maxn*2,inf);
clr0(inq),clr0(cnt);
}
void add(int u,int v,int w)
{
e[ecnt] = edge(v,w,head[u]);
head[u] = ecnt++;
// e[ecnt] = edge(u,w,head[v]);
// head[v] = ecnt++;
}
typedef pair<int,int> p2;
struct cmp {
bool operator() (const p2 &a, const p2 &b)
{
if(dist[a.first][a.second] != dist[b.first][b.second])
return dist[a.first][a.second] > dist[b.first][b.second];
else
return a.first > b.first;
}
};
void spfa(int src,int dst)
{
priority_queue<p2 , vector<p2> , cmp> q;
q.push(make_pair(src,0));
dist[src][0] = 0,cnt[src][0] = 1;
while(!q.empty()){
int u = q.top().first,flag = q.top().second;
q.pop();
if(inq[u][flag]) continue;
inq[u][flag] = 1;
for(int i = head[u];i != -1;i = e[i].next){
int v = e[i].v,w = e[i].w;
if(!inq[v][0] && dist[v][0] > dist[u][flag] + e[i].w){
if(dist[v][0] != inf){
dist[v][1] = dist[v][0];
cnt[v][1] = cnt[v][0];
q.push(make_pair(v,1));
}
dist[v][0] = dist[u][flag] + e[i].w;
cnt[v][0] = cnt[u][flag]; q.push(make_pair(v,0));
}else if(!inq[v][0] && dist[v][0] == dist[u][flag] + e[i].w){
cnt[v][0] += cnt[u][flag];
}else if(!inq[v][1] && dist[v][1] > dist[u][flag] + e[i].w){
dist[v][1] = dist[u][flag] + e[i].w;
cnt[v][1] = cnt[u][flag]; q.push(make_pair(v,1));
}else if(!inq[v][1] && dist[v][1] == dist[u][flag] + e[i].w){
cnt[v][1] += cnt[u][flag];
}
}
}
printf("%d %d\n",dist[dst][1],cnt[dst][1]);
} int main(){
int u,v,w,s,t;
while(~RD2(n,m)){
RD2(s,t);s++,t++;
init();
while(m--){
RD3(u,v,w);u++,v++;
add(u,v,w);
}
spfa(s,t);
}
return 0;
}

上面是错误代码

经过筛查,发现是

if(dist[a.first][a.second] != dist[b.first][b.second])
return dist[a.first][a.second] > dist[b.first][b.second];

有问题,因为不同的路径到达同一个点的同一个状态的值不一样,所有比较和更新穿插在一起就会出错了

可是每次更新dist数组都是向小了更新,所以不应该有影响啊..?

以下是AC代码,谁能清楚一点地告诉为啥上面的程序就不对呢?

#pragma comment(linker, "/STACK:36777216")
#pragma GCC optimize ("O2")
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define clr0(x) memset(x,0,sizeof(x))
#define clr1(x) memset(x,-1,sizeof(x))
#define eps 1e-9
const double pi = acos(-1.0);
typedef long long LL;
typedef unsigned long long ULL;
const int modo = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int inf = 0x3fffffff;
const LL _inf = 1e18;
const int maxn = 55,maxm = 10005;
struct edge{
int v,w,next;
edge(){};
edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};
}e[maxn*maxn*2];
int head[maxn],inq[maxn][2],dist[maxn][2],cnt[maxn][2];//0最短1次短
int n,m,ecnt;
struct node{
int v,flag,dis;
node(int a,int b,int c):v(a),flag(b),dis(c){};
bool operator < (const node & a) const{
if(a.dis == dis)
return a.v < v;
return a.dis < dis;
}
};
void init()
{
clr1(head);
ecnt = 0;
for(int i = 0;i <= n;++i)
dist[i][0] = dist[i][1] = inf;
//fill(dist,dist+maxn*2,inf);
clr0(inq),clr0(cnt);
}
void add(int u,int v,int w)
{
e[ecnt] = edge(v,w,head[u]);
head[u] = ecnt++;
// e[ecnt] = edge(u,w,head[v]);
// head[v] = ecnt++;
}
void spfa(int src,int dst)
{
priority_queue<node> q;
q.push(node(src,0,0));
dist[src][0] = 0,cnt[src][0] = 1;
while(!q.empty()){
int u = q.top().v,flag = q.top().flag,dis = q.top().dis;
q.pop();
if(inq[u][flag]) continue;
inq[u][flag] = 1;
for(int i = head[u];i != -1;i = e[i].next){
int v = e[i].v,w = e[i].w;
if(!inq[v][0] && dist[v][0] > dis + e[i].w){
if(dist[v][0] != inf){
dist[v][1] = dist[v][0];
cnt[v][1] = cnt[v][0];
q.push(node(v,1,dist[v][1]));
}
dist[v][0] = dis + e[i].w;
cnt[v][0] = cnt[u][flag]; q.push(node(v,0,dist[v][0]));
}else if(!inq[v][0] && dist[v][0] == dis + e[i].w){
cnt[v][0] += cnt[u][flag];
}else if(!inq[v][1] && dist[v][1] > dis + e[i].w){
dist[v][1] = dis + e[i].w;
cnt[v][1] = cnt[u][flag]; q.push(node(v,1,dist[v][1]));
}else if(!inq[v][1] && dist[v][1] == dis+ e[i].w){
cnt[v][1] += cnt[u][flag];
}
}
}
printf("%d %d\n",dist[dst][1],cnt[dst][1]);
} int main(){
int u,v,w,s,t;
while(~RD2(n,m)){
RD2(s,t);s++,t++;
init();
while(m--){
RD3(u,v,w);u++,v++;
add(u,v,w);
}
spfa(s,t);
}
return 0;
}

AC代码2

#pragma comment(linker, "/STACK:36777216")
#pragma GCC optimize ("O2")
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define clr0(x) memset(x,0,sizeof(x))
#define clr1(x) memset(x,-1,sizeof(x))
#define eps 1e-9
const double pi = acos(-1.0);
typedef long long LL;
typedef unsigned long long ULL;
const int modo = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int inf = 0x3fffffff;
const LL _inf = 1e18;
const int maxn = 55,maxm = 10005;
struct edge{
int v,w,next;
edge(){};
edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};
}e[maxn*maxn*2];
int head[maxn],inq[maxn][2],dist[maxn][2],cnt[maxn][2];//0最短1次短
int n,m,ecnt;
struct node{
int v,flag,dis;
node(int a,int b,int c):v(a),flag(b),dis(c){};
bool operator < (const node & a) const{
if(a.dis == dis)
return a.v < v;
return a.dis < dis;
}
};
void init()
{
clr1(head);
ecnt = 0;
for(int i = 0;i <= n;++i)
dist[i][0] = dist[i][1] = inf;
//fill(dist,dist+maxn*2,inf);
clr0(inq),clr0(cnt);
}
void add(int u,int v,int w)
{
e[ecnt] = edge(v,w,head[u]);
head[u] = ecnt++;
// e[ecnt] = edge(u,w,head[v]);
// head[v] = ecnt++;
}
void spfa(int src,int dst)
{
priority_queue<node> q;
q.push(node(src,0,0));
dist[src][0] = 0,cnt[src][0] = 1;
while(!q.empty()){
int u = q.top().v,flag = q.top().flag;//dis = q.top().dis;
q.pop();
if(inq[u][flag]) continue;
inq[u][flag] = 1;
for(int i = head[u];i != -1;i = e[i].next){
int v = e[i].v,w = e[i].w;
if(!inq[v][0] && dist[v][0] > dist[u][flag] + e[i].w){
if(dist[v][0] != inf){
dist[v][1] = dist[v][0];
cnt[v][1] = cnt[v][0];
q.push(node(v,1,dist[v][1]));
}
dist[v][0] = dist[u][flag] + e[i].w;
cnt[v][0] = cnt[u][flag]; q.push(node(v,0,dist[v][0]));
}else if(!inq[v][0] && dist[v][0] == dist[u][flag] + e[i].w){
cnt[v][0] += cnt[u][flag];
}else if(!inq[v][1] && dist[v][1] > dist[u][flag] + e[i].w){
dist[v][1] = dist[u][flag] + e[i].w;
cnt[v][1] = cnt[u][flag]; q.push(node(v,1,dist[v][1]));
}else if(!inq[v][1] && dist[v][1] == dist[u][flag] + e[i].w){
cnt[v][1] += cnt[u][flag];
}
}
}
printf("%d %d\n",dist[dst][1],cnt[dst][1]);
} int main(){
int u,v,w,s,t;
while(~RD2(n,m)){
RD2(s,t);s++,t++;
init();
while(m--){
RD3(u,v,w);u++,v++;
add(u,v,w);
}
spfa(s,t);
}
return 0;
}

#pragma comment(linker, "/STACK:36777216")#pragma GCC optimize ("O2")#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <string>#include
<queue>#include <map>#include <iostream>#include <algorithm>using namespace std;#define RD(x) scanf("%d",&x)#define RD2(x,y) scanf("%d%d",&x,&y)#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)#define clr0(x) memset(x,0,sizeof(x))#define clr1(x) memset(x,-1,sizeof(x))#define
eps 1e-9const double pi = acos(-1.0);typedef long long LL;typedef unsigned long long ULL;const int modo = 1e9 + 7;const int INF = 0x3f3f3f3f;const int inf = 0x3fffffff;const LL _inf = 1e18;const int maxn = 55,maxm = 10005;struct edge{ int v,w,next; edge(){};
edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};}e[maxn*maxn*2];int head[maxn],inq[maxn][2],dist[maxn][2],cnt[maxn][2];//0最短1次短int n,m,ecnt;void init(){ clr1(head); ecnt = 0; for(int i = 0;i < maxn;++i) dist[i][0] = dist[i][1] = inf; //fill(dist,dist+maxn*2,inf);
clr0(inq),clr0(cnt);}void add(int u,int v,int w){ e[ecnt] = edge(v,w,head[u]); head[u] = ecnt++;// e[ecnt] = edge(u,w,head[v]);// head[v] = ecnt++;}typedef pair<int,int> p2;struct cmp { bool operator() (const p2 &a, const p2 &b) { if(dist[a.first][a.second]
!= dist[b.first][b.second]) return dist[a.first][a.second] > dist[b.first][b.second]; else return a.first > b.first; }};void spfa(int src,int dst){ priority_queue<p2 , vector<p2> , cmp> q; q.push(make_pair(src,0)); dist[src][0] = 0,cnt[src][0] = 1; while(!q.empty()){
int u = q.top().first,flag = q.top().second; q.pop(); if(inq[u][flag]) continue; inq[u][flag] = 1; for(int i = head[u];i != -1;i = e[i].next){ int v = e[i].v,w = e[i].w; if(!inq[v][0] && dist[v][0] > dist[u][flag] + e[i].w){ if(dist[v][0] != inf){ dist[v][1]
= dist[v][0]; cnt[v][1] = cnt[v][0]; q.push(make_pair(v,1)); } dist[v][0] = dist[u][flag] + e[i].w; cnt[v][0] = cnt[u][flag]; q.push(make_pair(v,0)); }else if(!inq[v][0] && dist[v][0] == dist[u][flag] + e[i].w){ cnt[v][0] += cnt[u][flag]; }else if(!inq[v][1]
&& dist[v][1] > dist[u][flag] + e[i].w){ dist[v][1] = dist[u][flag] + e[i].w; cnt[v][1] = cnt[u][flag]; q.push(make_pair(v,1)); }else if(!inq[v][1] && dist[v][1] == dist[u][flag] + e[i].w){ cnt[v][1] += cnt[u][flag]; } } } printf("%d %d\n",dist[dst][1],cnt[dst][1]);}int
main(){ int u,v,w,s,t; while(~RD2(n,m)){ RD2(s,t);s++,t++; init(); while(m--){ RD3(u,v,w);u++,v++; add(u,v,w); } spfa(s,t); } return 0;}

hdu 3191 次短路的长度和个数的更多相关文章

  1. HDU 3191 次短路长度和条数

    http://www.cnblogs.com/wally/archive/2013/04/16/3024490.html http://blog.csdn.net/me4546/article/det ...

  2. HDU3191-How many paths are there(次短路的长度及其个数)

    oooccc1 is a Software Engineer who has to ride to the work place every Monday through Friday. For a ...

  3. COJ 0579 4020求次短路的长度

    4020求次短路的长度 难度级别:C: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 在一个地图上共有N个路口(编号分别为1到N),R条道路( ...

  4. HDU - 2066 最短路+加一个节点

    一个图上,有M条边,Z个出发点,Y个终止点.求一条最短路,其中起点是Z中的任意一点,终点是Y中任意一点. Input 输入数据有多组,输入直到文件结束. 每组的第一行是三个整数M,Z,Y 接着有M行, ...

  5. ACM: HDU 2544 最短路-Dijkstra算法

    HDU 2544最短路 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Descrip ...

  6. 【最长下降子序列的长度和个数】 poj 1952

    转自http://blog.csdn.net/zhang360896270/article/details/6701589 这题要求最长下降子序列的长度和个数,我们可以增加数组maxlen[size] ...

  7. UESTC 30 &&HDU 2544最短路【Floyd求解裸题】

    最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  8. hdu 5521 最短路

    Meeting Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  9. HDU 5726 GCD 区间GCD=k的个数

    GCD Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submis ...

随机推荐

  1. Notification 通知传值

    通知 是在跳转控制器之间常用的传值代理方式,除了代理模式,通知更方便.便捷,一个简单的Demo实现通知的跳转传值.       输入所要发送的信息 ,同时将label的值通过button方法调用传递, ...

  2. 发送邮件--MFMailComposeViewController

    只能在真机使用. 模拟器没有E-mail发送功能.无法调用 #import "EmailViewController.h" #import <UIKit/UIKit.h> ...

  3. 大神的P图过程!快来偷窥!

    来自美国的艺术家James(@jameasons) 平时我们总是能看到一些大神合成出这样的图片, 但是他们P图的过程是怎样的,很多人都是不知道的. 接下来再看看这位大神的其他作品, 如果你看了上面视频 ...

  4. UI设计教程分享:让你彻底读懂字体

    一份普普通通.规规矩矩的设计 一份让人印象深刻.新颖有趣的设计 差在哪?其实就差在三个字上! “优秀的设计不是每一个细节都有亮点,而是弱化其他元素,让某一个亮点最大化.” 今天“骉叔的设计心得”就来总 ...

  5. 会调色了不起吗? SORRY,会调色真的了不起!

    其实,现实的世界,大部分都是非常普通和常见的.所以调色师才有他们发挥的空间.如何把镜头中的世界变成梦幻一般. 把画面的颜色统一之后,逼格马上提升了很多! 发现表情不对,从其他照片把表情P回来,哈哈 这 ...

  6. Spring 属性注入(二)BeanWrapper 结构

    Spring 属性注入(二)BeanWrapper 结构 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) BeanWrap ...

  7. Sliding Window Median LT480

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...

  8. 关于Spring父容器和SpringMvc子容器

    在SSM项目中,会有SpringMvc容器(子容器)和Spring容器(父容器) 一共2个容器 基本规则: 子容器可以访问父容器的bean,父容器不能访问子容器的bean. 当<context: ...

  9. reduce 之 mixin实现

    语法: arr.reduce(callback[, initialValue]) 参数:    callback:执行数组中每个值的函数,包含四个参数:    accumulator:累加器累加回调的 ...

  10. barcode(index)

    在很多情况下,我们需要把多个样本混合在一起,在同一个通道(lane)里完成测序.像转录组测序.miRNA测序.lncRNA测序.ChIP测序等等,通常每个样本所需要的数据量都比较少,远少于HiSeq一 ...